//===--- Expr.h - Swift Language Expression ASTs ----------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the Expr class and subclasses.
//
//===----------------------------------------------------------------------===//

#ifndef POLARPHP_AST_EXPR_H
#define POLARPHP_AST_EXPR_H

#include "polarphp/ast/CaptureInfo.h"
#include "polarphp/ast/ConcreteDeclRef.h"
#include "polarphp/ast/DeclContext.h"
#include "polarphp/ast/DeclNameLoc.h"
#include "polarphp/ast/FunctionRefKind.h"
#include "polarphp/ast/InterfaceConformanceRef.h"
#include "polarphp/ast/TrailingCallArguments.h"
#include "polarphp/ast/TypeAlignments.h"
#include "polarphp/ast/TypeLoc.h"
#include "polarphp/ast/Type.h"
#include "polarphp/ast/Availability.h"
#include "polarphp/basic/Debug.h"
#include "polarphp/basic/InlineBitfield.h"
#include "llvm/Support/TrailingObjects.h"
#include <utility>

namespace llvm {
struct fltSemantics;
}

namespace polar {
enum class AccessKind : unsigned char;
class ArchetypeType;
class AstContext;
class AvailabilitySpec;
class IdentTypeRepr;
class Type;
class TypeRepr;
class ValueDecl;
class Decl;
class DeclRefExpr;
class OpenedArchetypeType;
class ParamDecl;
class Pattern;
class SubscriptDecl;
class Stmt;
class BraceStmt;
class AstWalker;
class Initializer;
class VarDecl;
class OpaqueValueExpr;
class FuncDecl;
class ConstructorDecl;
class TypeDecl;
class PatternBindingDecl;
class ParameterList;
class EnumElementDecl;
class CallExpr;
class KeyPathExpr;

using polar::count_bits_used;
using polar::bitmax;
using llvm::isa;
using llvm::cast;
using llvm::dyn_cast;

enum class ExprKind : uint8_t {
#define EXPR(Id, Parent) Id,
#define LAST_EXPR(Id) Last_Expr = Id,
#define EXPR_RANGE(Id, FirstId, LastId) \
   First_##Id##Expr = FirstId, Last_##Id##Expr = LastId,
#include "polarphp/ast/ExprNodesDef.h"
};
enum : unsigned
{
   NumExprKindBits =
   count_bits_used(static_cast<unsigned>(ExprKind::Last_Expr)) };

/// Discriminates certain kinds of checked cast that have specialized diagnostic
/// and/or code generation peephole behavior.
///
/// This enumeration should not have any semantic effect on the behavior of a
/// well-typed program, since the runtime can perform all casts that are
/// statically accepted.
enum class CheckedCastKind : unsigned
{
   Unresolved, // The kind has not been determined yet.
   First_Resolved, // Valid resolved kinds start here.
   Coercion = First_Resolved, // The requested cast is an implicit conversion, so this is a coercion.
   ValueCast, // A checked cast with no known specific behavior.
   ArrayDowncast, // A downcast from an array type to another array type.
   DictionaryDowncast, // A downcast from a dictionary type to another dictionary type.
   SetDowncast, // A downcast from a set type to another set type.
   BridgingCoercion, // A bridging conversion that always succeeds.
   Last_CheckedCastKind = BridgingCoercion,
};

//
/// What are the high-level semantics of this access?
enum class AccessSemantics : uint8_t
{
   /// On a storage reference, this is a direct access to the underlying
   /// physical storage, bypassing any observers.  The declaration must be
   /// a variable with storage.
   ///
   /// On a function reference, this is a non-polymorphic access to a
   /// particular implementation.
   DirectToStorage,

   /// On a storage reference, this is a direct access to the concrete
   /// implementation of this storage, bypassing any possibility of override.
   DirectToImplementation,

   /// This is an ordinary access to a declaration, using whatever
   /// polymorphism is expected.
   Ordinary,
};

/// Expr - Base class for all expressions in polar.
class alignas(8) Expr {
   Expr(const Expr &) = delete;

   void operator=(const Expr &) = delete;

protected:
   union {
      uint64_t OpaqueBits;

      POLAR_INLINE_BITFIELD_BASE(
      Expr, bitmax(NumExprKindBits, 8) + 1,
      /// The subclass of Expr that this is.
      Kind :
         bitmax(NumExprKindBits, 8),
      /// Whether the Expr represents something directly written in source or
      /// it was implicitly generated by the type-checker.
      Implicit :
         1
      );

      POLAR_INLINE_BITFIELD_FULL(CollectionExpr, Expr, 64 - NumExprBits,
      /// True if the type of this collection expr was inferred by the collection
      /// fallback type, like [Any].
                                 IsTypeDefaulted :
                                    1,
      /// Number of comma source locations.
                                 NumCommas :
                                    32 - 1 - NumExprBits,
      /// Number of entries in the collection. If this is a DictionaryExpr,
      /// each entry is a Tuple with the key and value pair.
                                 NumSubExprs :
                                    32
      );

      POLAR_INLINE_BITFIELD_EMPTY(LiteralExpr, Expr);
      POLAR_INLINE_BITFIELD_EMPTY(IdentityExpr, Expr);
      POLAR_INLINE_BITFIELD(LookupExpr, Expr, 1,
                            IsSuper :
                               1
      );
      POLAR_INLINE_BITFIELD_EMPTY(DynamicLookupExpr, LookupExpr);

      POLAR_INLINE_BITFIELD(ParenExpr, IdentityExpr, 1,
      /// Whether we're wrapping a trailing closure expression.
                            HasTrailingClosure :
                               1
      );

      POLAR_INLINE_BITFIELD(NumberLiteralExpr, LiteralExpr, 1 + 1,
                            IsNegative :
                               1,
                            IsExplicitConversion :
                               1
      );

      POLAR_INLINE_BITFIELD(StringLiteralExpr, LiteralExpr, 3 + 1 + 1,
                            Encoding :
                               3,
                            IsSingleUnicodeScalar :
                               1,
                            IsSingleExtendedGraphemeCluster :
                               1
      );

      POLAR_INLINE_BITFIELD_FULL(InterpolatedStringLiteralExpr, LiteralExpr, 32 + 20,
                                 : NumPadBits,
                                 InterpolationCount :
                                    20,
                                 LiteralCapacity :
                                    32
      );

      POLAR_INLINE_BITFIELD(DeclRefExpr, Expr, 2 + 2,
                            Semantics :
                               2, // an AccessSemantics
                            FunctionRefKind :
                               2
      );

      POLAR_INLINE_BITFIELD(UnresolvedDeclRefExpr, Expr, 2 + 2,
                            DeclRefKind :
                               2,
                            FunctionRefKind :
                               2
      );

      POLAR_INLINE_BITFIELD(MemberRefExpr, LookupExpr, 2,
                            Semantics :
                               2 // an AccessSemantics
      );

      POLAR_INLINE_BITFIELD_FULL(TupleElementExpr, Expr, 32,
                                 : NumPadBits,
                                 FieldNo :
                                    32
      );

      POLAR_INLINE_BITFIELD_FULL(TupleExpr, Expr, 1 + 1 + 1 + 32,
      /// Whether this tuple has a trailing closure.
                                 HasTrailingClosure :
                                    1,

      /// Whether this tuple has any labels.
                                 HasElementNames :
                                    1,

      /// Whether this tuple has label locations.
                                 HasElementNameLocations :
                                    1,

                                 : NumPadBits,
                                 NumElements :
                                    32
      );

      POLAR_INLINE_BITFIELD(UnresolvedDotExpr, Expr, 2,
                            FunctionRefKind :
                               2
      );

      POLAR_INLINE_BITFIELD_FULL(SubscriptExpr, LookupExpr, 2 + 1 + 1 + 16,
                                 Semantics :
                                    2, // an AccessSemantics
      /// Whether the SubscriptExpr also has source locations for the argument
      /// label.
                                 HasArgLabelLocs :
                                    1,
      /// Whether the last argument is a trailing closure.
                                 HasTrailingClosure :
                                    1,
                                 : NumPadBits,
      /// # of argument labels stored after the SubscriptExpr.
                                 NumArgLabels :
                                    16
      );

      POLAR_INLINE_BITFIELD_FULL(DynamicSubscriptExpr, DynamicLookupExpr, 1 + 1 + 16,
      /// Whether the DynamicSubscriptExpr also has source locations for the
      /// argument label.
                                 HasArgLabelLocs :
                                    1,
      /// Whether the last argument is a trailing closure.
                                 HasTrailingClosure :
                                    1,
                                 : NumPadBits,
      /// # of argument labels stored after the DynamicSubscriptExpr.
                                 NumArgLabels :
                                    16
      );

      POLAR_INLINE_BITFIELD_FULL(UnresolvedMemberExpr, Expr, 1 + 1 + 1 + 16,
      /// Whether the UnresolvedMemberExpr has arguments.
                                 HasArguments :
                                    1,
      /// Whether the UnresolvedMemberExpr also has source locations for the
      /// argument label.
                                 HasArgLabelLocs :
                                    1,
      /// Whether the last argument is a trailing closure.
                                 HasTrailingClosure :
                                    1,
                                 : NumPadBits,
      /// # of argument labels stored after the UnresolvedMemberExpr.
                                 NumArgLabels :
                                    16
      );

      POLAR_INLINE_BITFIELD(OverloadSetRefExpr, Expr, 2,
                            FunctionRefKind :
                               2
      );

      POLAR_INLINE_BITFIELD(BooleanLiteralExpr, LiteralExpr, 1,
                            Value :
                               1
      );

      POLAR_INLINE_BITFIELD(MagicIdentifierLiteralExpr, LiteralExpr, 3 + 1,
                            Kind :
                               3,
                            StringEncoding :
                               1
      );

      POLAR_INLINE_BITFIELD_FULL(ObjectLiteralExpr, LiteralExpr, 3 + 1 + 1 + 16,
                                 LitKind :
                                    3,
      /// Whether the ObjectLiteralExpr also has source locations for the argument
      /// label.
                                 HasArgLabelLocs :
                                    1,
      /// Whether the last argument is a trailing closure.
                                 HasTrailingClosure :
                                    1,
                                 : NumPadBits,
      /// # of argument labels stored after the ObjectLiteralExpr.
                                 NumArgLabels :
                                    16
      );

      POLAR_INLINE_BITFIELD(AbstractClosureExpr, Expr, (16 - NumExprBits) + 16,
                            : 16 - NumExprBits, // Align and leave room for subclasses
                            Discriminator :
                               16
      );

      POLAR_INLINE_BITFIELD(ClosureExpr, AbstractClosureExpr, 1,
      /// True if closure parameters were synthesized from anonymous closure
      /// variables.
                            HasAnonymousClosureVars :
                               1
      );

      POLAR_INLINE_BITFIELD_FULL(BindOptionalExpr, Expr, 16,
                                 : NumPadBits,
                                 Depth :
                                    16
      );

      POLAR_INLINE_BITFIELD_EMPTY(ImplicitConversionExpr, Expr);

      POLAR_INLINE_BITFIELD_FULL(DestructureTupleExpr, ImplicitConversionExpr, 16,
      /// The number of elements in the tuple type being destructured.
                                 NumElements :
                                    16
      );

      POLAR_INLINE_BITFIELD(ForceValueExpr, Expr, 1,
                            ForcedIUO :
                               1
      );

      POLAR_INLINE_BITFIELD(InOutToPointerExpr, ImplicitConversionExpr, 1,
                            IsNonAccessing :
                               1
      );

      POLAR_INLINE_BITFIELD(ArrayToPointerExpr, ImplicitConversionExpr, 1,
                            IsNonAccessing :
                               1
      );

      POLAR_INLINE_BITFIELD_FULL(ErasureExpr, ImplicitConversionExpr, 32,
                                 : NumPadBits,
                                 NumConformances :
                                    32
      );

      POLAR_INLINE_BITFIELD_FULL(UnresolvedSpecializeExpr, Expr, 32,
                                 : NumPadBits,
                                 NumUnresolvedParams :
                                    32
      );

      POLAR_INLINE_BITFIELD_FULL(CaptureListExpr, Expr, 32,
                                 : NumPadBits,
                                 NumCaptures :
                                    32
      );

      POLAR_INLINE_BITFIELD(ApplyExpr, Expr, 1 + 1,
                            ThrowsIsSet :
                               1,
                            Throws :
                               1
      );

      POLAR_INLINE_BITFIELD_FULL(CallExpr, ApplyExpr, 1 + 1 + 16,
      /// Whether the CallExpr also has source locations for the argument label.
                                 HasArgLabelLocs :
                                    1,
      /// Whether the last argument is a trailing closure.
                                 HasTrailingClosure :
                                    1,
                                 : NumPadBits,
      /// # of argument labels stored after the CallExpr.
                                 NumArgLabels :
                                    16
      );

      enum {
         NumCheckedCastKindBits = 4
      };
      POLAR_INLINE_BITFIELD(CheckedCastExpr, Expr, NumCheckedCastKindBits,
                            CastKind :
                               NumCheckedCastKindBits
      );
      static_assert(unsigned(CheckedCastKind::Last_CheckedCastKind)
                    < (1 << NumCheckedCastKindBits),
                    "unable to fit a CheckedCastKind in the given number of bits");

      POLAR_INLINE_BITFIELD_EMPTY(CollectionUpcastConversionExpr, Expr);

      POLAR_INLINE_BITFIELD(ObjCSelectorExpr, Expr, 2,
      /// The selector kind.
                            SelectorKind :
                               2
      );

      POLAR_INLINE_BITFIELD(KeyPathExpr, Expr, 1,
      /// Whether this is an ObjC stringified keypath.
                            IsObjC :
                               1
      );

      POLAR_INLINE_BITFIELD_FULL(SequenceExpr, Expr, 32,
                                 : NumPadBits,
                                 NumElements :
                                    32
      );

      POLAR_INLINE_BITFIELD(OpaqueValueExpr, Expr, 1,
                            IsPlaceholder :
                               1
      );

   } Bits;

private:
   /// Ty - This is the type of the expression.
   Type Ty;

protected:
   Expr(ExprKind Kind, bool Implicit, Type Ty = Type()) : Ty(Ty) {
      Bits.OpaqueBits = 0;
      Bits.Expr.Kind = unsigned(Kind);
      Bits.Expr.Implicit = Implicit;
   }

public:
   /// Return the kind of this expression.
   ExprKind getKind() const { return ExprKind(Bits.Expr.Kind); }

   /// Retrieve the name of the given expression kind.
   ///
   /// This name should only be used for debugging dumps and other
   /// developer aids, and should never be part of a diagnostic or exposed
   /// to the user of the compiler in any way.
   static StringRef getKindName(ExprKind K);

   /// getType - Return the type of this expression.
   Type getType() const { return Ty; }

   /// setType - Sets the type of this expression.
   void setType(Type T);

   /// Return the source range of the expression.
   SourceRange getSourceRange() const;

   /// getStartLoc - Return the location of the start of the expression.
   SourceLoc getStartLoc() const;

   /// Retrieve the location of the last token of the expression.
   SourceLoc getEndLoc() const;

   /// getLoc - Return the caret location of this expression.
   SourceLoc getLoc() const;

#define POLAR_FORWARD_SOURCE_LOCS_TO(SUBEXPR) \
   SourceLoc getStartLoc() const { return (SUBEXPR)->getStartLoc(); } \
   SourceLoc getEndLoc() const { return (SUBEXPR)->getEndLoc(); } \
   SourceLoc getLoc() const { return (SUBEXPR)->getLoc(); } \
   SourceRange getSourceRange() const { return (SUBEXPR)->getSourceRange(); }

   SourceLoc TrailingSemiLoc;

   /// getSemanticsProvidingExpr - Find the smallest subexpression
   /// which obeys the property that evaluating it is exactly
   /// equivalent to evaluating this expression.
   ///
   /// Looks through parentheses.  Would not look through something
   /// like '(foo(), x:bar(), baz()).x'.
   Expr *getSemanticsProvidingExpr();

   const Expr *getSemanticsProvidingExpr() const {
      return const_cast<Expr *>(this)->getSemanticsProvidingExpr();
   }

   /// getValueProvidingExpr - Find the smallest subexpression which is
   /// responsible for generating the value of this expression.
   /// Evaluating the result is not necessarily equivalent to
   /// evaluating this expression because of potential missing
   /// side-effects (which may influence the returned value).
   Expr *getValueProvidingExpr();

   const Expr *getValueProvidingExpr() const {
      return const_cast<Expr *>(this)->getValueProvidingExpr();
   }

   /// If this is a reference to an operator written as a member of a type (or
   /// extension thereof), return the underlying operator reference.
   DeclRefExpr *getMemberOperatorRef();

   /// This recursively walks the AST rooted at this expression.
   Expr *walk(AstWalker &walker);
   Expr *walk(AstWalker &&walker) { return walk(walker); }

   /// Enumerate each immediate child expression of this node, invoking the
   /// specific functor on it.  This ignores statements and other non-expression
   /// children.
   void forEachImmediateChildExpr(llvm::function_ref<Expr *(Expr *)> callback);

   /// Enumerate each expr node within this expression subtree, invoking the
   /// specific functor on it.  This ignores statements and other non-expression
   /// children, and if there is a closure within the expression, this does not
   /// walk into the body of it (unless it is single-expression).
   void forEachChildExpr(llvm::function_ref<Expr *(Expr *)> callback);

   /// Determine whether this expression refers to a type by name.
   ///
   /// This distinguishes static references to types, like Int, from metatype
   /// values, "someTy: Any.Type".
   bool isTypeReference(llvm::function_ref<Type(const Expr *)> getType =
   [](const Expr *E) -> Type { return E->getType(); },
   llvm::function_ref<Decl *(const Expr *)> getDecl =
   [](const Expr *E) -> Decl * {
      return nullptr;
   }) const;

   /// Determine whether this expression refers to a statically-derived metatype.
   ///
   /// This implies `isTypeReference`, but also requires that the referenced type
   /// is not an archetype or dependent type.
   bool isStaticallyDerivedMetatype(
   llvm::function_ref<Type(const Expr *)> getType =
   [](const Expr *E) -> Type { return E->getType(); },
   llvm::function_ref<bool(const Expr *)> isTypeReference =
   [](const Expr *E) { return E->isTypeReference(); }) const;

   /// isImplicit - Determines whether this expression was implicitly-generated,
   /// rather than explicitly written in the AST.
   bool isImplicit() const {
      return Bits.Expr.Implicit;
   }
   void setImplicit(bool Implicit = true) {
      Bits.Expr.Implicit = Implicit;
   }

   /// Retrieves the declaration that is being referenced by this
   /// expression, if any.
   ConcreteDeclRef getReferencedDecl() const;

   /// Determine whether this expression is 'super', possibly converted to
   /// a base class.
   bool isSuperExpr() const;

   /// Returns whether the semantically meaningful content of this expression is
   /// an inout expression.
   ///
   /// FIXME(Remove InOutType): This should eventually sub-in for
   /// 'E->getType()->is<InOutType>()' in all cases.
   bool isSemanticallyInOutExpr() const {
      return getSemanticsProvidingExpr()->getKind() == ExprKind::InOut;
   }

   /// Returns false if this expression needs to be wrapped in parens when
   /// used inside of a any postfix expression, true otherwise.
   ///
   /// \param appendingPostfixOperator if the expression being
   /// appended is a postfix operator like '!' or '?'.
   bool canAppendPostfixExpression(bool appendingPostfixOperator = false) const;

   /// Returns true if this is an infix operator of some sort, including
   /// a builtin operator.
   bool isInfixOperator() const;

   /// Returns true if this is a reference to the implicit self of function.
   bool isSelfExprOf(const AbstractFunctionDecl *AFD,
                     bool sameBase = false) const;

   /// Produce a mapping from each subexpression to its parent
   /// expression, with the provided expression serving as the root of
   /// the parent map.
   llvm::DenseMap<Expr *, Expr *> getParentMap();

   POLAR_DEBUG_DUMP;
   void dump(raw_ostream &OS, unsigned Indent = 0) const;
   void dump(raw_ostream &OS, llvm::function_ref<Type(const Expr *)> getType,
   llvm::function_ref<Type(const TypeLoc &)> getTypeOfTypeLoc,
   llvm::function_ref<Type(const KeyPathExpr *E, unsigned index)> getTypeOfKeyPathComponent,
   unsigned Indent = 0) const;

   void print(AstPrinter &Printer, const PrintOptions &Opts) const;

   // Only allow allocation of Exprs using the allocator in AstContext
   // or by doing a placement new.
   void *operator new(size_t Bytes, AstContext &C,
                      unsigned Alignment = alignof(Expr));

   // Make placement new and vanilla new/delete illegal for Exprs.
   void *operator new(size_t Bytes) noexcept = delete;
   void operator delete(void *Data) noexcept = delete;

   void *operator new(size_t Bytes, void *Mem) {
      assert(Mem);
      return Mem;
   }
};

/// ErrorExpr - Represents a semantically erroneous subexpression in the AST,
/// typically this will have an ErrorType.
class ErrorExpr : public Expr {
   SourceRange Range;
public:
   ErrorExpr(SourceRange Range, Type Ty = Type())
   : Expr(ExprKind::Error, /*Implicit=*/true, Ty), Range(Range) {}

   SourceRange getSourceRange() const { return Range; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Error;
   }
};

/// CodeCompletionExpr - Represents the code completion token in the AST, this
/// can help us preserve the context of the code completion position.
class CodeCompletionExpr : public Expr {
   SourceRange Range;

public:
   CodeCompletionExpr(SourceRange Range, Type Ty = Type())
   : Expr(ExprKind::CodeCompletion, /*Implicit=*/true, Ty), Range(Range) {}

   SourceRange getSourceRange() const { return Range; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CodeCompletion;
   }
};

/// LiteralExpr - Common base class between the literals.
class LiteralExpr : public Expr {
public:
   LiteralExpr(ExprKind Kind, bool Implicit) : Expr(Kind, Implicit) {}

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_LiteralExpr &&
             E->getKind() <= ExprKind::Last_LiteralExpr;
   }
};

/// The 'nil' literal.
///
class NilLiteralExpr : public LiteralExpr {
   SourceLoc Loc;
   ConcreteDeclRef Initializer;
public:
   NilLiteralExpr(SourceLoc Loc, bool Implicit = false)
   : LiteralExpr(ExprKind::NilLiteral, Implicit), Loc(Loc) {
   }

   SourceRange getSourceRange() const {
      return Loc;
   }

   /// Retrieve the initializer that will be used to construct the 'nil'
   /// literal from the result of the initializer.
   ConcreteDeclRef getInitializer() const { return Initializer; }

   /// Set the initializer that will be used to construct the 'nil' literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::NilLiteral;
   }
};

/// Abstract base class for numeric literals, potentially with a sign.
class NumberLiteralExpr : public LiteralExpr {
   /// The value of the literal as an AstContext-owned string. Underscores must
   /// be stripped.
   StringRef Val;  // Use StringRef instead of APInt or APFloat, which leak.
   ConcreteDeclRef BuiltinInitializer;
   ConcreteDeclRef Initializer;

protected:
   SourceLoc MinusLoc;
   SourceLoc DigitsLoc;

public:
   NumberLiteralExpr(ExprKind Kind,
                     StringRef Val, SourceLoc DigitsLoc, bool Implicit)
   : LiteralExpr(Kind, Implicit), Val(Val), DigitsLoc(DigitsLoc)
   {
      Bits.NumberLiteralExpr.IsNegative = false;
      Bits.NumberLiteralExpr.IsExplicitConversion = false;
   }

   bool isNegative() const { return Bits.NumberLiteralExpr.IsNegative; }
   void setNegative(SourceLoc Loc) {
      MinusLoc = Loc;
      Bits.NumberLiteralExpr.IsNegative = true;
   }

   bool isExplicitConversion() const {
      return Bits.NumberLiteralExpr.IsExplicitConversion;
   }
   void setExplicitConversion(bool isExplicitConversion = true) {
      Bits.NumberLiteralExpr.IsExplicitConversion = isExplicitConversion;
   }

   StringRef getDigitsText() const { return Val; }

   SourceRange getSourceRange() const {
      if (isNegative())
         return { MinusLoc, DigitsLoc };
      else
         return DigitsLoc;
   }

   SourceLoc getMinusLoc() const {
      return MinusLoc;
   }

   SourceLoc getDigitsLoc() const {
      return DigitsLoc;
   }

   /// Retrieve the builtin initializer that will be used to construct the
   /// boolean literal.
   ///
   /// Any type-checked boolean literal will have a builtin initializer, which is
   /// called first to form a concrete Swift type.
   ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }

   /// Set the builtin initializer that will be used to construct the boolean
   /// literal.
   void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      BuiltinInitializer = builtinInitializer;
   }

   /// Retrieve the initializer that will be used to construct the boolean
   /// literal from the result of the initializer.
   ///
   /// Only boolean literals that have no builtin literal conformance will have
   /// this initializer, which will be called on the result of the builtin
   /// initializer.
   ConcreteDeclRef getInitializer() const { return Initializer; }

   /// Set the initializer that will be used to construct the boolean literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_NumberLiteralExpr
             && E->getKind() <= ExprKind::Last_NumberLiteralExpr;
   }
};

/// Integer literal with a '+' or '-' sign, like '+4' or '- 2'.
///
/// After semantic analysis assigns types, this is guaranteed to have
/// a BuiltinIntegerType or be a normal type and implicitly be
/// AnyBuiltinIntegerType.
class IntegerLiteralExpr : public NumberLiteralExpr {
public:
   IntegerLiteralExpr(StringRef Val, SourceLoc DigitsLoc, bool Implicit = false)
   : NumberLiteralExpr(ExprKind::IntegerLiteral,
                       Val, DigitsLoc, Implicit)
   {}

   /// Returns a new integer literal expression with the given value.
   /// \p C The AST context.
   /// \p value The integer value.
   /// \return An implicit integer literal expression which evaluates to the value.
   static IntegerLiteralExpr *
   createFromUnsigned(AstContext &C, unsigned value);

   /// Returns the value of the literal, appropriately constructed in the
   /// target type.
   APInt getValue() const;

   /// Returns the raw value of the literal without any truncation.
   APInt getRawValue() const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::IntegerLiteral;
   }
};

/// FloatLiteralExpr - Floating point literal, like '4.0'.  After semantic
/// analysis assigns types, BuiltinTy is guaranteed to only have a
/// BuiltinFloatingPointType.
class FloatLiteralExpr : public NumberLiteralExpr {
   /// This is the type of the builtin literal.
   Type BuiltinTy;

public:
   FloatLiteralExpr(StringRef Val, SourceLoc Loc, bool Implicit = false)
   : NumberLiteralExpr(ExprKind::FloatLiteral, Val, Loc, Implicit)
   {}

   APFloat getValue() const;
   static APFloat getValue(StringRef Text, const llvm::fltSemantics &Semantics,
                           bool Negative);

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::FloatLiteral;
   }

   Type getBuiltinType() const { return BuiltinTy; }
   void setBuiltinType(Type ty) { BuiltinTy = ty; }
};

/// A Boolean literal ('true' or 'false')
///
class BooleanLiteralExpr : public LiteralExpr {
   SourceLoc Loc;
   ConcreteDeclRef BuiltinInitializer;
   ConcreteDeclRef Initializer;

public:
   BooleanLiteralExpr(bool Value, SourceLoc Loc, bool Implicit = false)
   : LiteralExpr(ExprKind::BooleanLiteral, Implicit), Loc(Loc) {
      Bits.BooleanLiteralExpr.Value = Value;
   }

   /// Retrieve the Boolean value of this literal.
   bool getValue() const { return Bits.BooleanLiteralExpr.Value; }

   SourceRange getSourceRange() const {
      return Loc;
   }

   /// Retrieve the builtin initializer that will be used to construct the
   /// boolean literal.
   ///
   /// Any type-checked boolean literal will have a builtin initializer, which is
   /// called first to form a concrete Swift type.
   ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }

   /// Set the builtin initializer that will be used to construct the boolean
   /// literal.
   void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      BuiltinInitializer = builtinInitializer;
   }

   /// Retrieve the initializer that will be used to construct the boolean
   /// literal from the result of the initializer.
   ///
   /// Only boolean literals that have no builtin literal conformance will have
   /// this initializer, which will be called on the result of the builtin
   /// initializer.
   ConcreteDeclRef getInitializer() const { return Initializer; }

   /// Set the initializer that will be used to construct the boolean literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::BooleanLiteral;
   }
};

/// StringLiteralExpr - String literal, like '"foo"'.
class StringLiteralExpr : public LiteralExpr {
   StringRef Val;
   SourceRange Range;
   ConcreteDeclRef BuiltinInitializer;
   ConcreteDeclRef Initializer;

public:
   /// The encoding that should be used for the string literal.
   enum Encoding : unsigned {
      /// A UTF-8 string.
      UTF8,

      /// A UTF-16 string.
      UTF16,

      /// A single UnicodeScalar, passed as an integer.
      OneUnicodeScalar
   };

   StringLiteralExpr(StringRef Val, SourceRange Range, bool Implicit = false);

   StringRef getValue() const { return Val; }
   SourceRange getSourceRange() const { return Range; }

   /// Determine the encoding that should be used for this string literal.
   Encoding getEncoding() const {
      return static_cast<Encoding>(Bits.StringLiteralExpr.Encoding);
   }

   /// Set the encoding that should be used for this string literal.
   void setEncoding(Encoding encoding) {
      Bits.StringLiteralExpr.Encoding = static_cast<unsigned>(encoding);
   }

   bool isSingleUnicodeScalar() const {
      return Bits.StringLiteralExpr.IsSingleUnicodeScalar;
   }

   bool isSingleExtendedGraphemeCluster() const {
      return Bits.StringLiteralExpr.IsSingleExtendedGraphemeCluster;
   }

   /// Retrieve the builtin initializer that will be used to construct the string
   /// literal.
   ///
   /// Any type-checked string literal will have a builtin initializer, which is
   /// called first to form a concrete Swift type.
   ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }

   /// Set the builtin initializer that will be used to construct the string
   /// literal.
   void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      BuiltinInitializer = builtinInitializer;
   }

   /// Retrieve the initializer that will be used to construct the string
   /// literal from the result of the initializer.
   ///
   /// Only string literals that have no builtin literal conformance will have
   /// this initializer, which will be called on the result of the builtin
   /// initializer.
   ConcreteDeclRef getInitializer() const { return Initializer; }

   /// Set the initializer that will be used to construct the string literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::StringLiteral;
   }
};

/// Runs a series of statements which use or modify \c SubExpr
/// before it is given to the rest of the expression.
///
/// \c Body should begin with a \c VarDecl; this defines the variable
/// \c TapExpr will initialize at the beginning and read a result
/// from at the end. \c TapExpr creates a separate scope, then
/// assigns the result of \c SubExpr to the variable and runs \c Body
/// in it, returning the value of the variable after the \c Body runs.
///
/// (The design here could be a bit cleaner, particularly where the VarDecl
/// is concerned.)
class TapExpr : public Expr {
   Expr *SubExpr;
   BraceStmt *Body;

public:
   TapExpr(Expr *SubExpr, BraceStmt *Body);

   Expr * getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr * se) { SubExpr = se; }

   /// The variable which will be accessed and possibly modified by
   /// the \c Body. This is the first \c ASTNode in the \c Body.
   VarDecl * getVar() const;

   BraceStmt * getBody() const { return Body; }
   void setBody(BraceStmt * b) { Body = b; }

   SourceLoc getLoc() const { return SubExpr ? SubExpr->getLoc() : SourceLoc(); }

   SourceLoc getStartLoc() const {
      return SubExpr ? SubExpr->getStartLoc() : SourceLoc();
   }

   SourceLoc getEndLoc() const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Tap;
   }
};

/// InterpolatedStringLiteral - An interpolated string literal.
///
/// An interpolated string literal mixes expressions (which are evaluated and
/// converted into string form) within a string literal.
///
/// \code
/// "[\(min)..\(max)]"
/// \endcode
class InterpolatedStringLiteralExpr : public LiteralExpr {
   /// Points at the beginning quote.
   SourceLoc Loc;
   /// Points at the ending quote.
   /// Needed for the upcoming \c ASTScope subsystem because lookups can be
   /// targeted to inside an \c InterpolatedStringLiteralExpr. It would be nicer
   /// to use \c EndLoc for this value, but then \c Lexer::getLocForEndOfToken()
   /// would not work for \c stringLiteral->getEndLoc().
   SourceLoc TrailingQuoteLoc;
   TapExpr *AppendingExpr;

   // Set by Sema:
   OpaqueValueExpr *interpolationExpr = nullptr;
   ConcreteDeclRef builderInit;
   ConcreteDeclRef resultInit;
   Expr *interpolationCountExpr = nullptr;
   Expr *literalCapacityExpr = nullptr;

public:
   InterpolatedStringLiteralExpr(SourceLoc Loc,
                                 SourceLoc TrailingQuoteLoc,
                                 unsigned LiteralCapacity,
                                 unsigned InterpolationCount,
                                 TapExpr *AppendingExpr)
   : LiteralExpr(ExprKind::InterpolatedStringLiteral, /*Implicit=*/false),
     Loc(Loc),
     TrailingQuoteLoc(TrailingQuoteLoc),
     AppendingExpr(AppendingExpr) {
      Bits.InterpolatedStringLiteralExpr.InterpolationCount = InterpolationCount;
      Bits.InterpolatedStringLiteralExpr.LiteralCapacity = LiteralCapacity;
   }

   // Sets the constructor for the interpolation type.
   void setBuilderInit(ConcreteDeclRef decl) { builderInit = decl; }
   ConcreteDeclRef getBuilderInit() const { return builderInit; }

   /// Sets the decl that constructs the final result type after the
   /// AppendingExpr has been evaluated.
   void setResultInit(ConcreteDeclRef decl) { resultInit = decl; }
   ConcreteDeclRef getResultInit() const { return resultInit; }

   /// Sets the OpaqueValueExpr that is passed into AppendingExpr as the SubExpr
   /// that the tap operates on.
   void setInterpolationExpr(OpaqueValueExpr *expr) { interpolationExpr = expr; }
   OpaqueValueExpr *getInterpolationExpr() const { return interpolationExpr; }

   /// Store a builtin integer literal expr wrapping getInterpolationCount().
   /// This is an arg to builderInit.
   void setInterpolationCountExpr(Expr *expr) { interpolationCountExpr = expr; }
   Expr *getInterpolationCountExpr() const { return interpolationCountExpr; }

   /// Store a builtin integer literal expr wrapping getLiteralCapacity().
   /// This is an arg to builderInit.
   void setLiteralCapacityExpr(Expr *expr) { literalCapacityExpr = expr; }
   Expr *getLiteralCapacityExpr() const { return literalCapacityExpr; }

   /// Retrieve the value of the literalCapacity parameter to the
   /// initializer.
   unsigned getLiteralCapacity() const {
      return Bits.InterpolatedStringLiteralExpr.LiteralCapacity;
   }

   /// Retrieve the value of the interpolationCount parameter to the
   /// initializer.
   unsigned getInterpolationCount() const {
      return Bits.InterpolatedStringLiteralExpr.InterpolationCount;
   }

   /// A block containing expressions which call
   /// \c StringInterpolationInterface methods to append segments to the
   /// string interpolation. The first node in \c Body should be an uninitialized
   /// \c VarDecl; the other statements should append to it.
   TapExpr * getAppendingExpr() const { return AppendingExpr; }
   void setAppendingExpr(TapExpr * AE) { AppendingExpr = AE; }

   SourceLoc getStartLoc() const {
      return Loc;
   }
   SourceLoc getEndLoc() const {
      // SourceLocs are token based, and the interpolated string is one string
      // token, so the range should be (Start == End).
      return Loc;
   }

   /// Could also be computed by relexing.
   SourceLoc getTrailingQuoteLoc() const {
      return TrailingQuoteLoc;
   }

   /// Call the \c callback with information about each segment in turn.
   void forEachSegment(AstContext &Ctx,
                       llvm::function_ref<void(bool, CallExpr *)> callback);

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InterpolatedStringLiteral;
   }
};

/// MagicIdentifierLiteralExpr - A magic identifier like #file which expands
/// out to a literal at SILGen time.
class MagicIdentifierLiteralExpr : public LiteralExpr {
public:
   enum Kind : unsigned {
      File, Line, Column, Function, DSOHandle
   };
private:
   SourceLoc Loc;
   ConcreteDeclRef BuiltinInitializer;
   ConcreteDeclRef Initializer;

public:
   MagicIdentifierLiteralExpr(Kind kind, SourceLoc loc, bool implicit = false)
   : LiteralExpr(ExprKind::MagicIdentifierLiteral, implicit), Loc(loc) {
      Bits.MagicIdentifierLiteralExpr.Kind = static_cast<unsigned>(kind);
      Bits.MagicIdentifierLiteralExpr.StringEncoding
      = static_cast<unsigned>(StringLiteralExpr::UTF8);
   }

   Kind getKind() const {
      return static_cast<Kind>(Bits.MagicIdentifierLiteralExpr.Kind);
   }

   bool isFile() const { return getKind() == File; }
   bool isFunction() const { return getKind() == Function; }
   bool isLine() const { return getKind() == Line; }
   bool isColumn() const { return getKind() == Column; }

   bool isString() const {
      switch (getKind()) {
         case File:
         case Function:
            return true;
         case Line:
         case Column:
         case DSOHandle:
            return false;
      }
      llvm_unreachable("bad Kind");
   }

   SourceRange getSourceRange() const { return Loc; }

   // For a magic identifier that produces a string literal, retrieve the
   // encoding for that string literal.
   StringLiteralExpr::Encoding getStringEncoding() const {
      assert(isString() && "Magic identifier literal has non-string encoding");
      return static_cast<StringLiteralExpr::Encoding>(
      Bits.MagicIdentifierLiteralExpr.StringEncoding);
   }

   // For a magic identifier that produces a string literal, set the encoding
   // for the string literal.
   void setStringEncoding(StringLiteralExpr::Encoding encoding) {
      assert(isString() && "Magic identifier literal has non-string encoding");
      Bits.MagicIdentifierLiteralExpr.StringEncoding
      = static_cast<unsigned>(encoding);
   }

   /// Retrieve the builtin initializer that will be used to construct the
   /// literal.
   ///
   /// Any type-checked literal will have a builtin initializer, which is
   /// called first to form a concrete Swift type.
   ConcreteDeclRef getBuiltinInitializer() const {
      return BuiltinInitializer;
   }

   /// Set the builtin initializer that will be used to construct the literal.
   void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
      BuiltinInitializer = builtinInitializer;
   }

   /// Retrieve the initializer that will be used to construct the literal from
   /// the result of the initializer.
   ///
   /// Only literals that have no builtin literal conformance will have
   /// this initializer, which will be called on the result of the builtin
   /// initializer.
   ConcreteDeclRef getInitializer() const {
      return Initializer;
   }

   /// Set the initializer that will be used to construct the literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MagicIdentifierLiteral;
   }
};

// ObjectLiteralExpr - An expression of the form
// '#colorLiteral(red: 1, blue: 0, green: 0, alpha: 1)' with a name and a list
// argument. The components of the list argument are meant to be themselves
// constant.
class ObjectLiteralExpr final
: public LiteralExpr,
  public TrailingCallArguments<ObjectLiteralExpr> {
public:
   /// The kind of object literal.
   enum LiteralKind : unsigned {
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) Name,
#include "polarphp/llparser/TokenKindsDef.h"
   };

private:
   Expr *Arg;
   SourceLoc PoundLoc;
   ConcreteDeclRef Initializer;

   ObjectLiteralExpr(SourceLoc PoundLoc, LiteralKind LitKind,
                     Expr *Arg,
                     ArrayRef<Identifier> argLabels,
                     ArrayRef<SourceLoc> argLabelLocs,
                     bool hasTrailingClosure,
                     bool implicit);

public:
   /// Create a new object literal expression.
   ///
   /// Note: prefer to use the second entry point, which separates out
   /// arguments/labels/etc.
   static ObjectLiteralExpr *
   create(AstContext &ctx, SourceLoc poundLoc, LiteralKind kind, Expr *arg,
          bool implicit, llvm::function_ref<Type(const Expr *)> getType);

   /// Create a new object literal expression.
   static ObjectLiteralExpr *create(AstContext &ctx, SourceLoc poundLoc,
                                    LiteralKind kind,
                                    SourceLoc lParenLoc,
                                    ArrayRef<Expr *> args,
                                    ArrayRef<Identifier> argLabels,
                                    ArrayRef<SourceLoc> argLabelLocs,
                                    SourceLoc rParenLoc,
                                    Expr *trailingClosure,
                                    bool implicit);

   LiteralKind getLiteralKind() const {
      return static_cast<LiteralKind>(Bits.ObjectLiteralExpr.LitKind);
   }

   Expr *getArg() const { return Arg; }
   void setArg(Expr *arg) { Arg = arg; }

   unsigned getNumArguments() const {
      return Bits.ObjectLiteralExpr.NumArgLabels;
   }
   bool hasArgumentLabelLocs() const {
      return Bits.ObjectLiteralExpr.HasArgLabelLocs;
   }

   /// Whether this call with written with a trailing closure.
   bool hasTrailingClosure() const {
      return Bits.ObjectLiteralExpr.HasTrailingClosure;
   }

   SourceLoc getSourceLoc() const { return PoundLoc; }
   SourceRange getSourceRange() const {
      return SourceRange(PoundLoc, Arg->getEndLoc());
   }

   /// Return the string form of the literal name.
   StringRef getLiteralKindRawName() const;

   StringRef getLiteralKindPlainName() const;

   /// Retrieve the initializer that will be used to construct the 'object'
   /// literal from the result of the initializer.
   ConcreteDeclRef getInitializer() const { return Initializer; }

   /// Set the initializer that will be used to construct the 'object' literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ObjectLiteral;
   }
};

/// DiscardAssignmentExpr - A '_' in the left-hand side of an assignment, which
/// discards the corresponding tuple element on the right-hand side.
class DiscardAssignmentExpr : public Expr {
   SourceLoc Loc;

public:
   DiscardAssignmentExpr(SourceLoc Loc, bool Implicit)
   : Expr(ExprKind::DiscardAssignment, Implicit), Loc(Loc) {}

   SourceRange getSourceRange() const { return Loc; }
   SourceLoc getLoc() const { return Loc; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DiscardAssignment;
   }
};

/// DeclRefExpr - A reference to a value, "x".
class DeclRefExpr : public Expr {
   /// The declaration pointer.
   ConcreteDeclRef D;
   DeclNameLoc Loc;

public:
   DeclRefExpr(ConcreteDeclRef D, DeclNameLoc Loc, bool Implicit,
               AccessSemantics semantics = AccessSemantics::Ordinary,
               Type Ty = Type())
   : Expr(ExprKind::DeclRef, Implicit, Ty), D(D), Loc(Loc) {
      Bits.DeclRefExpr.Semantics = (unsigned) semantics;
      Bits.DeclRefExpr.FunctionRefKind =
      static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
                                             : FunctionRefKind::Unapplied);
   }

   /// Retrieve the declaration to which this expression refers.
   ValueDecl *getDecl() const {
      return getDeclRef().getDecl();
   }

   /// Return true if this access is direct, meaning that it does not call the
   /// getter or setter.
   AccessSemantics getAccessSemantics() const {
      return (AccessSemantics) Bits.DeclRefExpr.Semantics;
   }

   /// Retrieve the concrete declaration reference.
   ConcreteDeclRef getDeclRef() const {
      return D;
   }

   SourceRange getSourceRange() const { return Loc.getSourceRange(); }
   SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
   DeclNameLoc getNameLoc() const { return Loc; }

   /// Retrieve the kind of function reference.
   FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(Bits.DeclRefExpr.FunctionRefKind);
   }

   /// Set the kind of function reference.
   void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.DeclRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DeclRef;
   }
};

/// A reference to 'super'. References to members of 'super' resolve to members
/// of a superclass of 'self'.
class SuperRefExpr : public Expr {
   VarDecl *Self;
   SourceLoc Loc;

public:
   SuperRefExpr(VarDecl *Self, SourceLoc Loc, bool Implicit,
                Type SuperTy = Type())
   : Expr(ExprKind::SuperRef, Implicit, SuperTy), Self(Self), Loc(Loc) {}

   VarDecl *getSelf() const { return Self; }

   SourceLoc getSuperLoc() const { return Loc; }
   SourceRange getSourceRange() const { return Loc; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::SuperRef;
   }
};

/// A reference to a type in expression context, spelled out as a TypeLoc. Sema
/// forms this expression as a result of name binding.  This always has
/// MetaTypetype.
class TypeExpr : public Expr {
   TypeLoc Info;
   TypeExpr(Type Ty);
public:
   // Create a TypeExpr with location information.
   TypeExpr(TypeLoc Ty);

   // The type of a TypeExpr is always a metatype type.  Return the instance
   // type, ErrorType if an error, or null if not set yet.
   Type getInstanceType(llvm::function_ref<bool(const Expr *)> hasType =
   [](const Expr *E) -> bool { return !!E->getType(); },
                        llvm::function_ref<Type(const Expr *)> getType =
                        [](const Expr *E) -> Type {
                           return E->getType();
                        }) const;

   // Create an implicit TypeExpr, which has no location information.
   static TypeExpr *createImplicit(Type Ty, AstContext &C) {
      return new (C) TypeExpr(Ty);
   }

   // Create an implicit TypeExpr, with location information even though it
   // shouldn't have one.  This is presently used to work around other location
   // processing bugs.  If you have an implicit location, use createImplicit.
   static TypeExpr *createImplicitHack(SourceLoc Loc, Type Ty, AstContext &C);


   /// Create a TypeExpr for a TypeDecl at the specified location.
   static TypeExpr *createForDecl(SourceLoc Loc, TypeDecl *D,
                                  DeclContext *DC,
                                  bool isImplicit);

   /// Create a TypeExpr for a member TypeDecl of the given parent TypeDecl.
   static TypeExpr *createForMemberDecl(SourceLoc ParentNameLoc,
                                        TypeDecl *Parent,
                                        SourceLoc NameLoc,
                                        TypeDecl *Decl);

   /// Create a TypeExpr for a member TypeDecl of the given parent IdentTypeRepr.
   static TypeExpr *createForMemberDecl(IdentTypeRepr *ParentTR,
                                        SourceLoc NameLoc,
                                        TypeDecl *Decl);

   /// Create a TypeExpr from an IdentTypeRepr with the given arguments applied
   /// at the specified location.
   ///
   /// Returns nullptr if the reference cannot be formed, which is a hack due
   /// to limitations in how we model generic typealiases.
   static TypeExpr *createForSpecializedDecl(IdentTypeRepr *ParentTR,
                                             ArrayRef<TypeRepr*> Args,
                                             SourceRange AngleLocs,
                                             AstContext &C);

   TypeLoc &getTypeLoc() { return Info; }
   TypeLoc getTypeLoc() const { return Info; }
   TypeRepr *getTypeRepr() const { return Info.getTypeRepr(); }
   // NOTE: TypeExpr::getType() returns the type of the expr node, which is the
   // metatype of what is stored as an operand type.

   SourceRange getSourceRange() const { return Info.getSourceRange(); }
   // TODO: optimize getStartLoc() and getEndLoc() when TypeLoc allows it.

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Type;
   }
};



/// A reference to another initializer from within a constructor body,
/// either to a delegating initializer or to a super.init invocation.
/// For a reference type, this semantically references a different constructor
/// entry point, called the 'initializing constructor', from the 'allocating
/// constructor' entry point referenced by a 'new' expression.
class OtherConstructorDeclRefExpr : public Expr {
   ConcreteDeclRef Ctor;
   DeclNameLoc Loc;

public:
   OtherConstructorDeclRefExpr(ConcreteDeclRef Ctor, DeclNameLoc Loc,
                               bool Implicit, Type Ty = {})
   : Expr(ExprKind::OtherConstructorDeclRef, Implicit, Ty),
     Ctor(Ctor), Loc(Loc)
   {}

   ConstructorDecl *getDecl() const;
   ConcreteDeclRef getDeclRef() const { return Ctor; }

   SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
   DeclNameLoc getConstructorLoc() const { return Loc; }
   SourceRange getSourceRange() const { return Loc.getSourceRange(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OtherConstructorDeclRef;
   }
};

/// OverloadSetRefExpr - A reference to an overloaded set of values with a
/// single name.
///
/// This is an abstract class that covers the various different kinds of
/// overload sets.
class OverloadSetRefExpr : public Expr {
   ArrayRef<ValueDecl*> Decls;

protected:
   OverloadSetRefExpr(ExprKind Kind, ArrayRef<ValueDecl*> decls,
                      FunctionRefKind functionRefKind, bool Implicit, Type Ty)
   : Expr(Kind, Implicit, Ty), Decls(decls) {
      Bits.OverloadSetRefExpr.FunctionRefKind =
      static_cast<unsigned>(functionRefKind);
   }

public:
   ArrayRef<ValueDecl*> getDecls() const { return Decls; }

   void setDecls(ArrayRef<ValueDecl *> domain) {
      Decls = domain;
   }

   /// getBaseType - Determine the type of the base object provided for the
   /// given overload set, which is only non-null when dealing with an overloaded
   /// member reference.
   Type getBaseType() const;

   /// hasBaseObject - Determine whether this overloaded expression has a
   /// concrete base object (which is not a metatype).
   bool hasBaseObject() const;

   /// Retrieve the kind of function reference.
   FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(
      Bits.OverloadSetRefExpr.FunctionRefKind);
   }

   /// Set the kind of function reference.
   void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.OverloadSetRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
   }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_OverloadSetRefExpr &&
             E->getKind() <= ExprKind::Last_OverloadSetRefExpr;
   }
};

/// OverloadedDeclRefExpr - A reference to an overloaded name that should
/// eventually be resolved (by overload resolution) to a value reference.
class OverloadedDeclRefExpr final : public OverloadSetRefExpr {
   DeclNameLoc Loc;

public:
   OverloadedDeclRefExpr(ArrayRef<ValueDecl*> Decls, DeclNameLoc Loc,
                         FunctionRefKind functionRefKind,
                         bool Implicit, Type Ty = Type())
   : OverloadSetRefExpr(ExprKind::OverloadedDeclRef, Decls, functionRefKind,
                        Implicit, Ty),
     Loc(Loc) {
   }

   DeclNameLoc getNameLoc() const { return Loc; }
   SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
   SourceRange getSourceRange() const { return Loc.getSourceRange(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OverloadedDeclRef;
   }
};

/// UnresolvedDeclRefExpr - This represents use of an undeclared identifier,
/// which may ultimately be a use of something that hasn't been defined yet, it
/// may be a use of something that got imported (which will be resolved during
/// sema), or may just be a use of an unknown identifier.
///
class UnresolvedDeclRefExpr : public Expr {
   DeclName Name;
   DeclNameLoc Loc;

public:
   UnresolvedDeclRefExpr(DeclName name, DeclRefKind refKind, DeclNameLoc loc)
   : Expr(ExprKind::UnresolvedDeclRef, /*Implicit=*/loc.isInvalid()),
     Name(name), Loc(loc) {
      Bits.UnresolvedDeclRefExpr.DeclRefKind = static_cast<unsigned>(refKind);
      Bits.UnresolvedDeclRefExpr.FunctionRefKind =
      static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
                                             : FunctionRefKind::Unapplied);
   }

   bool hasName() const { return static_cast<bool>(Name); }
   DeclName getName() const { return Name; }

   DeclRefKind getRefKind() const {
      return static_cast<DeclRefKind>(Bits.UnresolvedDeclRefExpr.DeclRefKind);
   }

   /// Retrieve the kind of function reference.
   FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(
      Bits.UnresolvedDeclRefExpr.FunctionRefKind);
   }

   /// Set the kind of function reference.
   void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.UnresolvedDeclRefExpr.FunctionRefKind = static_cast<unsigned>(refKind);
   }

   DeclNameLoc getNameLoc() const { return Loc; }

   SourceRange getSourceRange() const { return Loc.getSourceRange(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedDeclRef;
   }
};

/// LookupExpr - This abstract class represents 'a.b', 'a[]', etc where we
/// are referring to a member of a type, such as a property, variable, etc.
class LookupExpr : public Expr {
   Expr *Base;
   ConcreteDeclRef Member;

protected:
   explicit LookupExpr(ExprKind Kind, Expr *base, ConcreteDeclRef member,
                       bool Implicit)
   : Expr(Kind, Implicit), Base(base), Member(member) {
      Bits.LookupExpr.IsSuper = false;
      assert(Base);
   }

public:
   /// Retrieve the base of the expression.
   Expr *getBase() const { return Base; }

   /// Replace the base of the expression.
   void setBase(Expr *E) { Base = E; }

   /// Retrieve the member to which this access refers.
   ConcreteDeclRef getMember() const { return Member; }

   /// Determine whether the operation has a known underlying declaration or not.
   bool hasDecl() const { return static_cast<bool>(Member); }

   /// Retrieve the declaration that this /// operation refers to.
   /// Only valid when \c hasDecl() is true.
   ConcreteDeclRef getDecl() const {
      assert(hasDecl() && "No subscript declaration known!");
      return getMember();
   }

   /// Determine whether this reference refers to the superclass's property.
   bool isSuper() const { return Bits.LookupExpr.IsSuper; }

   /// Set whether this reference refers to the superclass's property.
   void setIsSuper(bool isSuper) { Bits.LookupExpr.IsSuper = isSuper; }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_LookupExpr &&
             E->getKind() <= ExprKind::Last_LookupExpr;
   }
};

/// MemberRefExpr - This represents 'a.b' where we are referring to a member
/// of a type, such as a property or variable.
///
/// Note that methods found via 'dot' syntax are expressed as DotSyntaxCallExpr
/// nodes, because 'a.f' is actually an application of 'a' (the implicit object
/// argument) to the function 'f'.
class MemberRefExpr : public LookupExpr {
   SourceLoc DotLoc;
   DeclNameLoc NameLoc;

public:
   MemberRefExpr(Expr *base, SourceLoc dotLoc, ConcreteDeclRef member,
                 DeclNameLoc loc, bool Implicit,
                 AccessSemantics semantics = AccessSemantics::Ordinary);
   SourceLoc getDotLoc() const { return DotLoc; }
   DeclNameLoc getNameLoc() const { return NameLoc; }

   /// Return true if this member access is direct, meaning that it
   /// does not call the getter or setter.
   AccessSemantics getAccessSemantics() const {
      return (AccessSemantics) Bits.MemberRefExpr.Semantics;
   }

   SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
   SourceLoc getStartLoc() const {
      SourceLoc BaseStartLoc = getBase()->getStartLoc();
      if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
         return NameLoc.getBaseNameLoc();
      } else {
         return BaseStartLoc;
      }
   }
   SourceLoc getEndLoc() const {
      return NameLoc.getSourceRange().end;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MemberRef;
   }
};

/// Common base for expressions that involve dynamic lookup, which
/// determines at runtime whether a particular method, property, or
/// subscript is available.
class DynamicLookupExpr : public LookupExpr {
protected:
   explicit DynamicLookupExpr(ExprKind kind, ConcreteDeclRef member, Expr *base)
   : LookupExpr(kind, base, member, /*Implicit=*/false) { }

public:
   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_DynamicLookupExpr &&
             E->getKind() <= ExprKind::Last_DynamicLookupExpr;
   }
};

/// A reference to a member of an object that was found via dynamic lookup.
///
/// A member found via dynamic lookup may not actually be available at runtime.
/// Therefore, a reference to that member always returns an optional instance.
/// Users can then propagate the optional (via ?) or assert that the member is
/// always available (via !). For example:
///
/// \code
/// class C {
///   func @objc foo(i : Int) -> String { ... }
/// };
///
/// var x : AnyObject = <some value>
/// print(x.foo!(17)) // x.foo has type ((i : Int) -> String)?
/// \endcode
class DynamicMemberRefExpr : public DynamicLookupExpr {
   SourceLoc DotLoc;
   DeclNameLoc NameLoc;

public:
   DynamicMemberRefExpr(Expr *base, SourceLoc dotLoc,
                        ConcreteDeclRef member,
                        DeclNameLoc nameLoc)
   : DynamicLookupExpr(ExprKind::DynamicMemberRef, member, base),
     DotLoc(dotLoc), NameLoc(nameLoc) {
   }

   /// Retrieve the location of the member name.
   DeclNameLoc getNameLoc() const { return NameLoc; }

   /// Retrieve the location of the '.'.
   SourceLoc getDotLoc() const { return DotLoc; }

   SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }

   SourceLoc getStartLoc() const {
      SourceLoc BaseStartLoc = getBase()->getStartLoc();
      if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
         return NameLoc.getBaseNameLoc();
      } else {
         return BaseStartLoc;
      }
   }
   SourceLoc getEndLoc() const { return NameLoc.getSourceRange().end; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DynamicMemberRef;
   }
};

/// A subscript on an object with dynamic lookup type.
///
/// A subscript found via dynamic lookup may not actually be available
/// at runtime.  Therefore, the result of performing the subscript
/// operation always returns an optional instance.Users can then
/// propagate the optional (via ?) or assert that the member is always
/// available (via !). For example:
///
/// \code
/// class C {
///   @objc subscript (i : Int) -> String {
///     get {
///       ...
///     }
///   }
/// };
///
/// var x : AnyObject = <some value>
/// print(x[27]! // x[27] has type String?
/// \endcode
class DynamicSubscriptExpr final
: public DynamicLookupExpr,
  public TrailingCallArguments<DynamicSubscriptExpr> {
   friend TrailingCallArguments;

   Expr *Index;

   DynamicSubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
                        ArrayRef<SourceLoc> argLabelLocs,
                        bool hasTrailingClosure, ConcreteDeclRef member,
                        bool implicit);

public:
   /// Create a dynamic subscript.
   ///
   /// Note: do not create new callers to this entry point; use the entry point
   /// that takes separate index arguments.
   static DynamicSubscriptExpr *
   create(AstContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl,
          bool implicit,
          llvm::function_ref<Type(const Expr *)> getType =
          [](const Expr *E) -> Type { return E->getType(); });

   /// Create a new dynamic subscript.
   static DynamicSubscriptExpr *create(AstContext &ctx, Expr *base,
                                       SourceLoc lSquareLoc,
                                       ArrayRef<Expr *> indexArgs,
                                       ArrayRef<Identifier> indexArgLabels,
                                       ArrayRef<SourceLoc> indexArgLabelLocs,
                                       SourceLoc rSquareLoc,
                                       Expr *trailingClosure,
                                       ConcreteDeclRef decl,
                                       bool implicit);

   /// getIndex - Retrieve the index of the subscript expression, i.e., the
   /// "offset" into the base value.
   Expr *getIndex() const { return Index; }
   void setIndex(Expr *E) { Index = E; }

   unsigned getNumArguments() const {
      return Bits.DynamicSubscriptExpr.NumArgLabels;
   }

   bool hasArgumentLabelLocs() const {
      return Bits.DynamicSubscriptExpr.HasArgLabelLocs;
   }

   /// Whether this call with written with a trailing closure.
   bool hasTrailingClosure() const {
      return Bits.DynamicSubscriptExpr.HasTrailingClosure;
   }

   SourceLoc getLoc() const { return Index->getStartLoc(); }

   SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
   SourceLoc getEndLoc() const { return Index->getEndLoc(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DynamicSubscript;
   }
};

/// UnresolvedMemberExpr - This represents '.foo', an unresolved reference to a
/// member, which is to be resolved with context sensitive type information into
/// bar.foo.  These always have unresolved type.
class UnresolvedMemberExpr final
: public Expr,
  public TrailingCallArguments<UnresolvedMemberExpr> {
   SourceLoc DotLoc;
   DeclNameLoc NameLoc;
   DeclName Name;
   Expr *Argument;

   UnresolvedMemberExpr(SourceLoc dotLoc, DeclNameLoc nameLoc,
                        DeclName name, Expr *argument,
                        ArrayRef<Identifier> argLabels,
                        ArrayRef<SourceLoc> argLabelLocs,
                        bool hasTrailingClosure,
                        bool implicit);

public:
   /// Create a new unresolved member expression with no arguments.
   static UnresolvedMemberExpr *create(AstContext &ctx, SourceLoc dotLoc,
                                       DeclNameLoc nameLoc, DeclName name,
                                       bool implicit);

   /// Create a new unresolved member expression.
   static UnresolvedMemberExpr *create(AstContext &ctx, SourceLoc dotLoc,
                                       DeclNameLoc nameLoc, DeclName name,
                                       SourceLoc lParenLoc,
                                       ArrayRef<Expr *> args,
                                       ArrayRef<Identifier> argLabels,
                                       ArrayRef<SourceLoc> argLabelLocs,
                                       SourceLoc rParenLoc,
                                       Expr *trailingClosure,
                                       bool implicit);

   DeclName getName() const { return Name; }
   DeclNameLoc getNameLoc() const { return NameLoc; }
   SourceLoc getDotLoc() const { return DotLoc; }
   Expr *getArgument() const { return Argument; }
   void setArgument(Expr *argument) { Argument = argument; }

   /// Whether this reference has arguments.
   bool hasArguments() const {
      return Bits.UnresolvedMemberExpr.HasArguments;
   }

   unsigned getNumArguments() const {
      return Bits.UnresolvedMemberExpr.NumArgLabels;
   }

   bool hasArgumentLabelLocs() const {
      return Bits.UnresolvedMemberExpr.HasArgLabelLocs;
   }

   /// Whether this call with written with a trailing closure.
   bool hasTrailingClosure() const {
      return Bits.UnresolvedMemberExpr.HasTrailingClosure;
   }

   SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }

   SourceLoc getStartLoc() const { return DotLoc; }
   SourceLoc getEndLoc() const {
      return (Argument ? Argument->getEndLoc() : NameLoc.getSourceRange().end);
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedMember;
   }
};

/// AnyTryExpr - An abstract superclass for 'try' and 'try!'.
///
/// These are like IdentityExpr in some ways, but they're a bit too
/// semantic differentiated to just always look through.
class AnyTryExpr : public Expr {
   Expr *SubExpr;
   SourceLoc TryLoc;

public:
   AnyTryExpr(ExprKind kind, SourceLoc tryLoc, Expr *sub,
              Type type, bool implicit)
   : Expr(kind, implicit, type), SubExpr(sub), TryLoc(tryLoc) {}

   SourceLoc getLoc() const { return SubExpr->getLoc(); }
   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *E) { SubExpr = E; }

   SourceLoc getTryLoc() const { return TryLoc; }

   SourceLoc getStartLoc() const { return TryLoc; }
   SourceLoc getEndLoc() const { return getSubExpr()->getEndLoc(); }

   static bool classof(const Expr *e) {
      return e->getKind() >= ExprKind::First_AnyTryExpr
             && e->getKind() <= ExprKind::Last_AnyTryExpr;
   }
};

/// TryExpr - A 'try' surrounding an expression, marking that the
/// expression contains code which might throw.
///
/// getSemanticsProvidingExpr() looks through this because it doesn't
/// provide the value and only very specific clients care where the
/// 'try' was written.
class TryExpr : public AnyTryExpr {
public:
   TryExpr(SourceLoc tryLoc, Expr *sub, Type type = Type(),
           bool implicit = false)
   : AnyTryExpr(ExprKind::Try, tryLoc, sub, type, implicit) {}

   static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::Try;
   }
};

/// ForceTryExpr - A 'try!' surrounding an expression, marking that
/// the expression contains code which might throw, but that the code
/// should dynamically assert if it does.
class ForceTryExpr : public AnyTryExpr {
   SourceLoc ExclaimLoc;

public:
   ForceTryExpr(SourceLoc tryLoc, Expr *sub, SourceLoc exclaimLoc,
                Type type = Type(), bool implicit = false)
   : AnyTryExpr(ExprKind::ForceTry, tryLoc, sub, type, implicit),
     ExclaimLoc(exclaimLoc) {}

   SourceLoc getExclaimLoc() const { return ExclaimLoc; }

   static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::ForceTry;
   }
};

/// A 'try?' surrounding an expression, marking that the expression contains
/// code which might throw, and that the result should be injected into an
/// Optional. If the code does throw, \c nil is produced.
class OptionalTryExpr : public AnyTryExpr {
   SourceLoc QuestionLoc;

public:
   OptionalTryExpr(SourceLoc tryLoc, Expr *sub, SourceLoc questionLoc,
                   Type type = Type(), bool implicit = false)
   : AnyTryExpr(ExprKind::OptionalTry, tryLoc, sub, type, implicit),
     QuestionLoc(questionLoc) {}

   SourceLoc getQuestionLoc() const { return QuestionLoc; }

   static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::OptionalTry;
   }
};

/// An expression node that does not affect the evaluation of its subexpression.
class IdentityExpr : public Expr {
   Expr *SubExpr;

public:
   IdentityExpr(ExprKind kind,
                Expr *subExpr, Type ty = Type(),
                bool implicit = false)
   : Expr(kind, implicit, ty), SubExpr(subExpr)
   {}

   SourceLoc getLoc() const { return SubExpr->getLoc(); }
   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *E) { SubExpr = E; }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_IdentityExpr
             && E->getKind() <= ExprKind::Last_IdentityExpr;
   }
};

/// The '.self' pseudo-property, which has no effect except to
/// satisfy the syntactic requirement that type values appear only as part of
/// a property chain.
class DotSelfExpr : public IdentityExpr {
   SourceLoc DotLoc;
   SourceLoc SelfLoc;

public:
   DotSelfExpr(Expr *subExpr, SourceLoc dot, SourceLoc self,
               Type ty = Type())
   : IdentityExpr(ExprKind::DotSelf, subExpr, ty),
     DotLoc(dot), SelfLoc(self)
   {}

   SourceLoc getDotLoc() const { return DotLoc; }
   SourceLoc getSelfLoc() const { return SelfLoc; }

   SourceLoc getStartLoc() const { return getSubExpr()->getStartLoc(); }
   SourceLoc getEndLoc() const { return SelfLoc; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DotSelf;
   }
};

/// A parenthesized expression like '(x+x)'.  Syntactically,
/// this is just a TupleExpr with exactly one element that has no label.
/// Semantically, however, it serves only as grouping parentheses and
/// does not form an expression of tuple type (unless the sub-expression
/// has tuple type, of course).
class ParenExpr : public IdentityExpr {
   SourceLoc LParenLoc, RParenLoc;

public:
   ParenExpr(SourceLoc lploc, Expr *subExpr, SourceLoc rploc,
             bool hasTrailingClosure,
             Type ty = Type())
   : IdentityExpr(ExprKind::Paren, subExpr, ty),
     LParenLoc(lploc), RParenLoc(rploc) {
      Bits.ParenExpr.HasTrailingClosure = hasTrailingClosure;
      assert(lploc.isValid() == rploc.isValid() &&
             "Mismatched source location information");
   }

   SourceLoc getLParenLoc() const { return LParenLoc; }
   SourceLoc getRParenLoc() const { return RParenLoc; }

   // When the locations of the parens are invalid, ask our
   // subexpression for its source range instead.  This isn't a
   // hot path and so we don't both optimizing for it.

   SourceLoc getStartLoc() const {
      return (LParenLoc.isInvalid() ? getSubExpr()->getStartLoc() : LParenLoc);
   }
   SourceLoc getEndLoc() const {
      // If we have a trailing closure, our end point is the end of the
      // trailing closure.
      if (RParenLoc.isInvalid() || Bits.ParenExpr.HasTrailingClosure)
         return getSubExpr()->getEndLoc();
      return RParenLoc;
   }

   /// Whether this expression has a trailing closure as its argument.
   bool hasTrailingClosure() const { return Bits.ParenExpr.HasTrailingClosure; }

   static bool classof(const Expr *E) { return E->getKind() == ExprKind::Paren; }
};

/// TupleExpr - Parenthesized expressions like '(a: x+x)' and '(x, y, 4)'.  Also
/// used to represent the operands to a binary operator.  Note that
/// expressions like '(4)' are represented with a ParenExpr.
class TupleExpr final : public Expr,
                        private llvm::TrailingObjects<TupleExpr, Expr *, Identifier, SourceLoc> {
   friend TrailingObjects;

   SourceLoc LParenLoc;
   SourceLoc RParenLoc;

   size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return getNumElements();
   }
   size_t numTrailingObjects(OverloadToken<Identifier>) const {
      return hasElementNames() ? getNumElements() : 0;
   }
   size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
      return hasElementNames() ? getNumElements() : 0;
   }

   /// Retrieve the buffer containing the element names.
   MutableArrayRef<Identifier> getElementNamesBuffer() {
      if (!hasElementNames())
         return { };

      return { getTrailingObjects<Identifier>(), getNumElements() };
   }

   /// Retrieve the buffer containing the element name locations.
   MutableArrayRef<SourceLoc> getElementNameLocsBuffer() {
      if (!hasElementNameLocs())
         return { };

      return { getTrailingObjects<SourceLoc>(), getNumElements() };
   }

   TupleExpr(SourceLoc LParenLoc, ArrayRef<Expr *> SubExprs,
             ArrayRef<Identifier> ElementNames,
             ArrayRef<SourceLoc> ElementNameLocs,
             SourceLoc RParenLoc, bool HasTrailingClosure, bool Implicit,
             Type Ty);

public:
   /// Create a tuple.
   static TupleExpr *create(AstContext &ctx,
                            SourceLoc LParenLoc,
                            ArrayRef<Expr *> SubExprs,
                            ArrayRef<Identifier> ElementNames,
                            ArrayRef<SourceLoc> ElementNameLocs,
                            SourceLoc RParenLoc, bool HasTrailingClosure,
                            bool Implicit, Type Ty = Type());

   /// Create an empty tuple.
   static TupleExpr *createEmpty(AstContext &ctx, SourceLoc LParenLoc,
                                 SourceLoc RParenLoc, bool Implicit);

   /// Create an implicit tuple with no source information.
   static TupleExpr *createImplicit(AstContext &ctx, ArrayRef<Expr *> SubExprs,
                                    ArrayRef<Identifier> ElementNames);

   SourceLoc getLParenLoc() const { return LParenLoc; }
   SourceLoc getRParenLoc() const { return RParenLoc; }

   SourceRange getSourceRange() const;

   /// Whether this expression has a trailing closure as its argument.
   bool hasTrailingClosure() const { return Bits.TupleExpr.HasTrailingClosure; }

   /// Retrieve the elements of this tuple.
   MutableArrayRef<Expr*> getElements() {
      return { getTrailingObjects<Expr *>(), getNumElements() };
   }

   /// Retrieve the elements of this tuple.
   ArrayRef<Expr*> getElements() const {
      return { getTrailingObjects<Expr *>(), getNumElements() };
   }

   unsigned getNumElements() const { return Bits.TupleExpr.NumElements; }

   Expr *getElement(unsigned i) const {
      return getElements()[i];
   }
   void setElement(unsigned i, Expr *e) {
      getElements()[i] = e;
   }

   /// Whether this tuple has element names.
   bool hasElementNames() const {
      return Bits.TupleExpr.HasElementNames;
   }

   /// Retrieve the element names for a tuple.
   ArrayRef<Identifier> getElementNames() const {
      return const_cast<TupleExpr *>(this)->getElementNamesBuffer();
   }

   /// Retrieve the ith element name.
   Identifier getElementName(unsigned i) const {
      return hasElementNames() ? getElementNames()[i] : Identifier();
   }

   /// Whether this tuple has element name locations.
   bool hasElementNameLocs() const {
      return Bits.TupleExpr.HasElementNameLocations;
   }

   /// Retrieve the locations of the element names for a tuple.
   ArrayRef<SourceLoc> getElementNameLocs() const {
      return const_cast<TupleExpr *>(this)->getElementNameLocsBuffer();
   }

   /// Retrieve the location of the ith label, if known.
   SourceLoc getElementNameLoc(unsigned i) const {
      if (hasElementNameLocs())
         return getElementNameLocs()[i];

      return SourceLoc();
   }

   static bool classof(const Expr *E) { return E->getKind() == ExprKind::Tuple; }
};

/// A collection literal expression.
///
/// The subexpression is represented as a TupleExpr or ParenExpr and
/// passed on to the appropriate semantics-providing conversion
/// operation.
class CollectionExpr : public Expr {
   SourceLoc LBracketLoc;
   SourceLoc RBracketLoc;
   ConcreteDeclRef Initializer;

   /// Retrieve the intrusive pointer storage from the subtype
   Expr *const *getTrailingObjectsPointer() const;
   Expr **getTrailingObjectsPointer() {
      const CollectionExpr *temp = this;
      return const_cast<Expr**>(temp->getTrailingObjectsPointer());
   }

   /// Retrieve the intrusive pointer storage from the subtype
   const SourceLoc *getTrailingSourceLocs() const;
   SourceLoc *getTrailingSourceLocs() {
      const CollectionExpr *temp = this;
      return const_cast<SourceLoc*>(temp->getTrailingSourceLocs());
   }

protected:
   CollectionExpr(ExprKind Kind, SourceLoc LBracketLoc,
                  ArrayRef<Expr*> Elements, ArrayRef<SourceLoc> CommaLocs,
                  SourceLoc RBracketLoc, Type Ty)
   : Expr(Kind, /*Implicit=*/false, Ty),
     LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc) {
      Bits.CollectionExpr.IsTypeDefaulted = false;
      Bits.CollectionExpr.NumSubExprs = Elements.size();
      Bits.CollectionExpr.NumCommas = CommaLocs.size();
      assert(Bits.CollectionExpr.NumCommas == CommaLocs.size() && "Truncation");
      std::uninitialized_copy(Elements.begin(), Elements.end(),
                              getTrailingObjectsPointer());
      std::uninitialized_copy(CommaLocs.begin(), CommaLocs.end(),
                              getTrailingSourceLocs());
   }

public:

   /// Retrieve the elements stored in the collection.
   ArrayRef<Expr *> getElements() const {
      return {getTrailingObjectsPointer(), Bits.CollectionExpr.NumSubExprs};
   }
   MutableArrayRef<Expr *> getElements() {
      return {getTrailingObjectsPointer(), Bits.CollectionExpr.NumSubExprs};
   }
   Expr *getElement(unsigned i) const { return getElements()[i]; }
   void setElement(unsigned i, Expr *E) { getElements()[i] = E; }
   unsigned getNumElements() const { return Bits.CollectionExpr.NumSubExprs; }

   /// Retrieve the comma source locations stored in the collection. Please note
   /// that trailing commas are currently allowed, and that invalid code may have
   /// stray or missing commas.
   MutableArrayRef<SourceLoc> getCommaLocs() {
      return {getTrailingSourceLocs(), static_cast<size_t>(Bits.CollectionExpr.NumCommas)};
   }
   ArrayRef<SourceLoc> getCommaLocs() const {
      return {getTrailingSourceLocs(), static_cast<size_t>(Bits.CollectionExpr.NumCommas)};
   }
   unsigned getNumCommas() const { return Bits.CollectionExpr.NumCommas; }

   bool isTypeDefaulted() const { return Bits.CollectionExpr.IsTypeDefaulted; }
   void setIsTypeDefaulted(bool value = true) {
      Bits.CollectionExpr.IsTypeDefaulted = value;
   }

   SourceLoc getLBracketLoc() const { return LBracketLoc; }
   SourceLoc getRBracketLoc() const { return RBracketLoc; }
   SourceRange getSourceRange() const {
      return SourceRange(LBracketLoc, RBracketLoc);
   }

   static bool classof(const Expr *e) {
      return e->getKind() >= ExprKind::First_CollectionExpr &&
             e->getKind() <= ExprKind::Last_CollectionExpr;
   }

   /// Retrieve the initializer that will be used to construct the 'array'
   /// literal from the result of the initializer.
   ConcreteDeclRef getInitializer() const { return Initializer; }

   /// Set the initializer that will be used to construct the 'array' literal.
   void setInitializer(ConcreteDeclRef initializer) {
      Initializer = initializer;
   }
};

/// An array literal expression [a, b, c].
class ArrayExpr final : public CollectionExpr,
                        private llvm::TrailingObjects<ArrayExpr, Expr*, SourceLoc> {
   friend TrailingObjects;
   friend CollectionExpr;

   size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return getNumElements();
   }
   size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
      return getNumCommas();
   }

   ArrayExpr(SourceLoc LBracketLoc, ArrayRef<Expr*> Elements,
             ArrayRef<SourceLoc> CommaLocs,
             SourceLoc RBracketLoc, Type Ty)
   : CollectionExpr(ExprKind::Array, LBracketLoc, Elements, CommaLocs,
                    RBracketLoc, Ty) { }
public:
   static ArrayExpr *create(AstContext &C, SourceLoc LBracketLoc,
                            ArrayRef<Expr*> Elements,
                            ArrayRef<SourceLoc> CommaLocs,
                            SourceLoc RBracketLoc,
                            Type Ty = Type());

   static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::Array;
   }

   Type getElementType();
};

/// A dictionary literal expression [a : x, b : y, c : z].
class DictionaryExpr final : public CollectionExpr,
                             private llvm::TrailingObjects<DictionaryExpr, Expr*, SourceLoc> {
   friend TrailingObjects;
   friend CollectionExpr;

   size_t numTrailingObjects(OverloadToken<Expr *>) const {
      return getNumElements();
   }
   size_t numTrailingObjects(OverloadToken<SourceLoc>) const {
      return getNumCommas();
   }

   DictionaryExpr(SourceLoc LBracketLoc, ArrayRef<Expr*> Elements,
                  ArrayRef<SourceLoc> CommaLocs,
                  SourceLoc RBracketLoc, Type Ty)
   : CollectionExpr(ExprKind::Dictionary, LBracketLoc, Elements, CommaLocs,
                    RBracketLoc, Ty) { }
public:

   static DictionaryExpr *create(AstContext &C, SourceLoc LBracketLoc,
                                 ArrayRef<Expr*> Elements,
                                 ArrayRef<SourceLoc> CommaLocs,
                                 SourceLoc RBracketLoc,
                                 Type Ty = Type());

   static bool classof(const Expr *e) {
      return e->getKind() == ExprKind::Dictionary;
   }

   Type getElementType();
};

/// Subscripting expressions like a[i] that refer to an element within a
/// container.
///
/// There is no built-in subscripting in the language. Rather, a fully
/// type-checked and well-formed subscript expression refers to a subscript
/// declaration, which provides a getter and (optionally) a setter that will
/// be used to perform reads/writes.
class SubscriptExpr final : public LookupExpr,
                            public TrailingCallArguments<SubscriptExpr> {
   friend TrailingCallArguments;

   Expr *Index;

   SubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
                 ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure,
                 ConcreteDeclRef decl, bool implicit, AccessSemantics semantics);

public:
   /// Create a subscript.
   ///
   /// Note: do not create new callers to this entry point; use the entry point
   /// that takes separate index arguments.
   static SubscriptExpr *
   create(AstContext &ctx, Expr *base, Expr *index,
          ConcreteDeclRef decl = ConcreteDeclRef(), bool implicit = false,
          AccessSemantics semantics = AccessSemantics::Ordinary,
          llvm::function_ref<Type(const Expr *)> getType =
          [](const Expr *E) -> Type { return E->getType(); });

   /// Create a new subscript.
   static SubscriptExpr *create(AstContext &ctx, Expr *base,
                                SourceLoc lSquareLoc,
                                ArrayRef<Expr *> indexArgs,
                                ArrayRef<Identifier> indexArgLabels,
                                ArrayRef<SourceLoc> indexArgLabelLocs,
                                SourceLoc rSquareLoc,
                                Expr *trailingClosure,
                                ConcreteDeclRef decl = ConcreteDeclRef(),
                                bool implicit = false,
                                AccessSemantics semantics
                                = AccessSemantics::Ordinary);

   /// getIndex - Retrieve the index of the subscript expression, i.e., the
   /// "offset" into the base value.
   Expr *getIndex() const { return Index; }
   void setIndex(Expr *E) { Index = E; }

   unsigned getNumArguments() const {
      return Bits.SubscriptExpr.NumArgLabels;
   }

   bool hasArgumentLabelLocs() const {
      return Bits.SubscriptExpr.HasArgLabelLocs;
   }

   /// Whether this call was written with a trailing closure.
   bool hasTrailingClosure() const {
      return Bits.SubscriptExpr.HasTrailingClosure;
   }

   /// Determine whether this subscript reference should bypass the
   /// ordinary accessors.
   AccessSemantics getAccessSemantics() const {
      return (AccessSemantics) Bits.SubscriptExpr.Semantics;
   }

   SourceLoc getLoc() const { return Index->getStartLoc(); }
   SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
   SourceLoc getEndLoc() const {
      auto end = Index->getEndLoc();
      return end.isValid() ? end : getBase()->getEndLoc();
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Subscript;
   }
};

/// Subscripting expression that applies a keypath to a base.
class KeyPathApplicationExpr : public Expr {
   Expr *Base;
   Expr *KeyPath;
   SourceLoc LBracketLoc, RBracketLoc;

public:
   KeyPathApplicationExpr(Expr *base, SourceLoc lBracket, Expr *keyPath,
                          SourceLoc rBracket, Type ty, bool implicit)
   : Expr(ExprKind::KeyPathApplication, implicit, ty),
     Base(base), KeyPath(keyPath), LBracketLoc(lBracket), RBracketLoc(rBracket)
   {}

   SourceLoc getLoc() const { return LBracketLoc; }
   SourceLoc getStartLoc() const { return Base->getStartLoc(); }
   SourceLoc getEndLoc() const { return RBracketLoc; }

   Expr *getBase() const { return Base; }
   void setBase(Expr *E) { Base = E; }
   Expr *getKeyPath() const { return KeyPath; }
   void setKeyPath(Expr *E) { KeyPath = E; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::KeyPathApplication;
   }
};

/// A member access (foo.bar) on an expression with unresolved type.
class UnresolvedDotExpr : public Expr {
   Expr *SubExpr;
   SourceLoc DotLoc;
   DeclNameLoc NameLoc;
   DeclName Name;
   ArrayRef<ValueDecl *> OuterAlternatives;

public:
   UnresolvedDotExpr(
   Expr *subexpr, SourceLoc dotloc, DeclName name, DeclNameLoc nameloc,
   bool Implicit,
   ArrayRef<ValueDecl *> outerAlternatives = ArrayRef<ValueDecl *>())
   : Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr),
     DotLoc(dotloc), NameLoc(nameloc), Name(name),
     OuterAlternatives(outerAlternatives) {
      Bits.UnresolvedDotExpr.FunctionRefKind =
      static_cast<unsigned>(NameLoc.isCompound() ? FunctionRefKind::Compound
                                                 : FunctionRefKind::Unapplied);
   }

   SourceLoc getLoc() const {
      if (NameLoc.isValid())
         return NameLoc.getBaseNameLoc();
      else if (DotLoc.isValid())
         return DotLoc;
      else
         return SubExpr->getEndLoc();
   }

   SourceLoc getStartLoc() const {
      auto SubLoc = SubExpr->getStartLoc();
      if (SubLoc.isValid())
         return SubLoc;
      else if (DotLoc.isValid())
         return DotLoc;
      else
         return NameLoc.getSourceRange().start;
   }
   SourceLoc getEndLoc() const {
      if (NameLoc.isValid())
         return NameLoc.getSourceRange().end;
      else if (DotLoc.isValid())
         return DotLoc;
      else
         return SubExpr->getEndLoc();
   }

   SourceLoc getDotLoc() const { return DotLoc; }
   Expr *getBase() const { return SubExpr; }
   void setBase(Expr *e) { SubExpr = e; }

   DeclName getName() const { return Name; }
   DeclNameLoc getNameLoc() const { return NameLoc; }

   ArrayRef<ValueDecl *> getOuterAlternatives() const {
      return OuterAlternatives;
   }

   /// Retrieve the kind of function reference.
   FunctionRefKind getFunctionRefKind() const {
      return static_cast<FunctionRefKind>(Bits.UnresolvedDotExpr.FunctionRefKind);
   }

   /// Set the kind of function reference.
   void setFunctionRefKind(FunctionRefKind refKind) {
      Bits.UnresolvedDotExpr.FunctionRefKind = static_cast<unsigned>(refKind);
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedDot;
   }
};

/// TupleElementExpr - Refer to an element of a tuple,
/// e.g. "(1,field:2).field".
class TupleElementExpr : public Expr {
   Expr *SubExpr;
   SourceLoc NameLoc;
   SourceLoc DotLoc;

public:
   TupleElementExpr(Expr *SubExpr, SourceLoc DotLoc, unsigned FieldNo,
                    SourceLoc NameLoc, Type Ty)
   : Expr(ExprKind::TupleElement, /*Implicit=*/false, Ty), SubExpr(SubExpr),
     NameLoc(NameLoc), DotLoc(DotLoc) {
      Bits.TupleElementExpr.FieldNo = FieldNo;
   }

   SourceLoc getLoc() const { return NameLoc; }
   Expr *getBase() const { return SubExpr; }
   void setBase(Expr *e) { SubExpr = e; }

   unsigned getFieldNumber() const { return Bits.TupleElementExpr.FieldNo; }
   SourceLoc getNameLoc() const { return NameLoc; }
   SourceLoc getDotLoc() const { return DotLoc; }

   SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
   SourceLoc getEndLoc() const { return getNameLoc(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::TupleElement;
   }
};

/// Describes a monadic bind from T? to T.
///
/// In a ?-chain expression, this is the part that's spelled with a
/// postfix ?.
///
/// A BindOptionalExpr must always appear within a
/// OptionalEvaluationExpr.  If the operand of the BindOptionalExpr
/// evaluates to a missing value, the OptionalEvaluationExpr
/// immediately completes and produces a missing value in the result
/// type.
///
/// The depth of the BindOptionalExpr indicates which
/// OptionalEvaluationExpr is completed, in case the BindOptionalExpr
/// is contained within more than one such expression.
class BindOptionalExpr : public Expr {
   Expr *SubExpr;
   SourceLoc QuestionLoc;

public:
   BindOptionalExpr(Expr *subExpr, SourceLoc questionLoc,
                    unsigned depth, Type ty = Type())
   : Expr(ExprKind::BindOptional, /*Implicit=*/ questionLoc.isInvalid(), ty),
     SubExpr(subExpr), QuestionLoc(questionLoc) {
      Bits.BindOptionalExpr.Depth = depth;
      assert(Bits.BindOptionalExpr.Depth == depth && "bitfield truncation");
   }

   SourceRange getSourceRange() const {
      if (QuestionLoc.isInvalid())
         return SubExpr->getSourceRange();
      return SourceRange(SubExpr->getStartLoc(), QuestionLoc);
   }
   SourceLoc getStartLoc() const {
      return SubExpr->getStartLoc();
   }
   SourceLoc getEndLoc() const {
      return (QuestionLoc.isInvalid() ? SubExpr->getEndLoc() : QuestionLoc);
   }
   SourceLoc getLoc() const {
      if (isImplicit())
         return SubExpr->getLoc();

      return getQuestionLoc();
   }
   SourceLoc getQuestionLoc() const { return QuestionLoc; }

   unsigned getDepth() const { return Bits.BindOptionalExpr.Depth; }
   void setDepth(unsigned depth) {
      Bits.BindOptionalExpr.Depth = depth;
   }

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *expr) { SubExpr = expr; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::BindOptional;
   }
};

/// Describes the outer limits of an operation containing
/// monadic binds of T? to T.
///
/// In a ?-chain expression, this is implicitly formed at the outer
/// limits of the chain.  For example, in (foo?.bar?().baz).fred,
/// this is nested immediately within the parens.
///
/// This expression will always have optional type.
class OptionalEvaluationExpr : public Expr {
   Expr *SubExpr;

public:
   OptionalEvaluationExpr(Expr *subExpr, Type ty = Type())
   : Expr(ExprKind::OptionalEvaluation, /*Implicit=*/ true, ty),
     SubExpr(subExpr) {}

   POLAR_FORWARD_SOURCE_LOCS_TO(SubExpr)

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *expr) { SubExpr = expr; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OptionalEvaluation;
   }
};

/// An expression that forces an optional to its underlying value.
///
/// \code
/// func parseInt(s : String) -> Int? { ... }
///
/// var maybeInt = parseInt("5")     // returns an Int?
/// var forcedInt = parseInt("5")!   // returns an Int; fails on empty optional
/// \endcode
///
class ForceValueExpr : public Expr {
   Expr *SubExpr;
   SourceLoc ExclaimLoc;

public:
   ForceValueExpr(Expr *subExpr, SourceLoc exclaimLoc, bool forcedIUO = false)
   : Expr(ExprKind::ForceValue, /*Implicit=*/exclaimLoc.isInvalid(), Type()),
     SubExpr(subExpr), ExclaimLoc(exclaimLoc) {
      Bits.ForceValueExpr.ForcedIUO = forcedIUO;
   }

   SourceRange getSourceRange() const {
      if (ExclaimLoc.isInvalid())
         return SubExpr->getSourceRange();

      return SourceRange(SubExpr->getStartLoc(), ExclaimLoc);
   }
   SourceLoc getStartLoc() const {
      return SubExpr->getStartLoc();
   }
   SourceLoc getEndLoc() const {
      return (isImplicit() ? SubExpr->getEndLoc() : getExclaimLoc());
   }
   SourceLoc getLoc() const {
      if (!isImplicit())
         return getExclaimLoc();

      return SubExpr->getLoc();
   }
   SourceLoc getExclaimLoc() const { return ExclaimLoc; }

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *expr) { SubExpr = expr; }

   bool isForceOfImplicitlyUnwrappedOptional() const {
      return Bits.ForceValueExpr.ForcedIUO;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ForceValue;
   }
};

/// An expression that grants temporary escapability to a nonescaping
/// closure value.
///
/// This expression is formed by the type checker when a call to the
/// `withoutActuallyEscaping` declaration is made.
class MakeTemporarilyEscapableExpr : public Expr {
   Expr *NonescapingClosureValue;
   OpaqueValueExpr *EscapingClosureValue;
   Expr *SubExpr;
   SourceLoc NameLoc, LParenLoc, RParenLoc;
   Expr *OriginalExpr;

public:
   MakeTemporarilyEscapableExpr(SourceLoc NameLoc,
                                SourceLoc LParenLoc,
                                Expr *NonescapingClosureValue,
                                Expr *SubExpr,
                                SourceLoc RParenLoc,
                                OpaqueValueExpr *OpaqueValueForEscapingClosure,
                                Expr *OriginalExpr,
                                bool implicit = false)
   : Expr(ExprKind::MakeTemporarilyEscapable, implicit, Type()),
     NonescapingClosureValue(NonescapingClosureValue),
     EscapingClosureValue(OpaqueValueForEscapingClosure),
     SubExpr(SubExpr),
     NameLoc(NameLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc),
     OriginalExpr(OriginalExpr)
   {}

   SourceLoc getStartLoc() const {
      return NameLoc;
   }
   SourceLoc getEndLoc() const {
      return RParenLoc;
   }

   SourceLoc getLoc() const {
      return NameLoc;
   }

   /// Retrieve the opaque value representing the escapable copy of the
   /// closure.
   OpaqueValueExpr *getOpaqueValue() const { return EscapingClosureValue; }

   /// Retrieve the nonescaping closure expression.
   Expr *getNonescapingClosureValue() const {
      return NonescapingClosureValue;
   }
   void setNonescapingClosureValue(Expr *e) {
      NonescapingClosureValue = e;
   }

   /// Retrieve the subexpression that has access to the escapable copy of the
   /// closure.
   Expr *getSubExpr() const {
      return SubExpr;
   }
   void setSubExpr(Expr *e) {
      SubExpr = e;
   }

   /// Retrieve the original 'withoutActuallyEscaping(closure) { ... }'
   //  expression.
   Expr *getOriginalExpr() const {
      return OriginalExpr;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MakeTemporarilyEscapable;
   }
};

/// An expression that opens up a value of protocol or protocol
/// composition type and gives a name to its dynamic type.
///
/// This expression is implicitly created by the type checker when
/// calling a method on a protocol. In the future, this may become an
/// actual operation within the language.
class OpenExistentialExpr : public Expr {
   Expr *ExistentialValue;
   OpaqueValueExpr *OpaqueValue;
   Expr *SubExpr;
   SourceLoc ExclaimLoc;

public:
   OpenExistentialExpr(Expr *existentialValue,
                       OpaqueValueExpr *opaqueValue,
                       Expr *subExpr,
                       Type subExprTy)
   : Expr(ExprKind::OpenExistential, /*Implicit=*/ true, subExprTy),
     ExistentialValue(existentialValue), OpaqueValue(opaqueValue),
     SubExpr(subExpr) { }

   POLAR_FORWARD_SOURCE_LOCS_TO(SubExpr)

   /// Retrieve the expression that is being evaluated using the
   /// archetype value.
   ///
   /// This subexpression (and no other) may refer to the archetype
   /// type or the opaque value that stores the archetype's value.
   Expr *getSubExpr() const { return SubExpr; }

   /// Set the subexpression that is being evaluated.
   void setSubExpr(Expr *expr) { SubExpr = expr; }

   /// Retrieve the existential value that is being opened.
   Expr *getExistentialValue() const { return ExistentialValue; }

   /// Set the existential val ue that is being opened.
   void setExistentialValue(Expr *expr) { ExistentialValue = expr; }

   /// Retrieve the opaque value representing the value (of archetype
   /// type) stored in the existential.
   OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }

   /// Retrieve the opened archetype, which can only be referenced
   /// within this expression's subexpression.
   OpenedArchetypeType *getOpenedArchetype() const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OpenExistential;
   }
};

/// ImplicitConversionExpr - An abstract class for expressions which
/// implicitly convert the value of an expression in some way.
class ImplicitConversionExpr : public Expr {
   Expr *SubExpr;

protected:
   ImplicitConversionExpr(ExprKind kind, Expr *subExpr, Type ty)
   : Expr(kind, /*Implicit=*/true, ty), SubExpr(subExpr) {}

public:
   POLAR_FORWARD_SOURCE_LOCS_TO(SubExpr)

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *e) { SubExpr = e; }

   Expr *getSyntacticSubExpr() const {
      if (auto *ICE = dyn_cast<ImplicitConversionExpr>(SubExpr))
         return ICE->getSyntacticSubExpr();
      return SubExpr;
   }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_ImplicitConversionExpr &&
             E->getKind() <= ExprKind::Last_ImplicitConversionExpr;
   }
};

/// The implicit conversion from a class metatype to AnyObject.
class ClassMetatypeToObjectExpr : public ImplicitConversionExpr {
public:
   ClassMetatypeToObjectExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::ClassMetatypeToObject, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ClassMetatypeToObject;
   }
};

/// The implicit conversion from a class existential metatype to AnyObject.
class ExistentialMetatypeToObjectExpr : public ImplicitConversionExpr {
public:
   ExistentialMetatypeToObjectExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::ExistentialMetatypeToObject, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ExistentialMetatypeToObject;
   }
};

/// The implicit conversion from a protocol value metatype to ObjC's Interface
/// class type.
class InterfaceMetatypeToObjectExpr : public ImplicitConversionExpr {
public:
   InterfaceMetatypeToObjectExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::InterfaceMetatypeToObject, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InterfaceMetatypeToObject;
   }
};

/// InjectIntoOptionalExpr - The implicit conversion from T to T?.
class InjectIntoOptionalExpr : public ImplicitConversionExpr {
public:
   InjectIntoOptionalExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::InjectIntoOptional, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InjectIntoOptional;
   }
};

/// Convert the address of an inout property to a pointer.
class InOutToPointerExpr : public ImplicitConversionExpr {
public:
   InOutToPointerExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::InOutToPointer, subExpr, ty) {
      Bits.InOutToPointerExpr.IsNonAccessing = false;
   }

   /// Is this conversion "non-accessing"?  That is, is it only using the
   /// pointer for its identity, as opposed to actually accessing the memory?
   bool isNonAccessing() const {
      return Bits.InOutToPointerExpr.IsNonAccessing;
   }
   void setNonAccessing(bool nonAccessing = true) {
      Bits.InOutToPointerExpr.IsNonAccessing = nonAccessing;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InOutToPointer;
   }
};

/// Convert the address of an array to a pointer.
class ArrayToPointerExpr : public ImplicitConversionExpr {
public:
   ArrayToPointerExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::ArrayToPointer, subExpr, ty) {
      Bits.ArrayToPointerExpr.IsNonAccessing = false;
   }

   /// Is this conversion "non-accessing"?  That is, is it only using the
   /// pointer for its identity, as opposed to actually accessing the memory?
   bool isNonAccessing() const {
      return Bits.ArrayToPointerExpr.IsNonAccessing;
   }
   void setNonAccessing(bool nonAccessing = true) {
      Bits.ArrayToPointerExpr.IsNonAccessing = nonAccessing;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ArrayToPointer;
   }
};

/// Convert the a string to a pointer referencing its encoded representation.
class StringToPointerExpr : public ImplicitConversionExpr {
public:
   StringToPointerExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::StringToPointer, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::StringToPointer;
   }
};

/// Convert a pointer to a different kind of pointer.
class PointerToPointerExpr : public ImplicitConversionExpr {
public:
   PointerToPointerExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::PointerToPointer, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::PointerToPointer;
   }
};

/// Convert between a foreign object and its corresponding Objective-C object.
class ForeignObjectConversionExpr : public ImplicitConversionExpr {
public:
   ForeignObjectConversionExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::ForeignObjectConversion, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ForeignObjectConversion;
   }
};

/// Construct an unevaluated instance of the underlying metatype.
class UnevaluatedInstanceExpr : public ImplicitConversionExpr {
public:
   UnevaluatedInstanceExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::UnevaluatedInstance, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnevaluatedInstance;
   }
};

/// Use an opaque type to abstract a value of the underlying concrete type.
class UnderlyingToOpaqueExpr : public ImplicitConversionExpr {
public:
   UnderlyingToOpaqueExpr(Expr *subExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::UnderlyingToOpaque, subExpr, ty) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnderlyingToOpaque;
   }
};

/// DestructureTupleExpr - Destructure a tuple value produced by a source
/// expression, binding the elements to OpaqueValueExprs, then evaluate the
/// result expression written in terms of the OpaqueValueExprs.
class DestructureTupleExpr final : public ImplicitConversionExpr,
                                   private llvm::TrailingObjects<DestructureTupleExpr, OpaqueValueExpr *> {
   friend TrailingObjects;

   size_t numTrailingObjects(OverloadToken<OpaqueValueExpr *>) const {
      return Bits.DestructureTupleExpr.NumElements;
   }

private:
   Expr *DstExpr;

   DestructureTupleExpr(ArrayRef<OpaqueValueExpr *> destructuredElements,
                        Expr *srcExpr, Expr *dstExpr, Type ty)
   : ImplicitConversionExpr(ExprKind::DestructureTuple, srcExpr, ty),
     DstExpr(dstExpr) {
      Bits.DestructureTupleExpr.NumElements = destructuredElements.size();
      std::uninitialized_copy(destructuredElements.begin(),
                              destructuredElements.end(),
                              getTrailingObjects<OpaqueValueExpr *>());
   }

public:
   /// Create a tuple destructuring. The type of srcExpr must be a tuple type,
   /// and the number of elements must equal the size of destructureElements.
   static DestructureTupleExpr *
   create(AstContext &ctx,
          ArrayRef<OpaqueValueExpr *> destructuredElements,
          Expr *srcExpr, Expr *dstExpr, Type ty);

   ArrayRef<OpaqueValueExpr *> getDestructuredElements() const {
      return {getTrailingObjects<OpaqueValueExpr *>(),
              static_cast<size_t>(Bits.DestructureTupleExpr.NumElements)};
   }

   Expr *getResultExpr() const {
      return DstExpr;
   }

   void setResultExpr(Expr *dstExpr) {
      DstExpr = dstExpr;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DestructureTuple;
   }
};

/// LoadExpr - Turn an l-value into an r-value by performing a "load"
/// operation.  This operation may actually be a logical operation,
/// i.e. one implemented using a call to a potentially user-defined
/// function instead of a simple memory transaction.
class LoadExpr : public ImplicitConversionExpr {
public:
   LoadExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::Load, subExpr, type) {}

   static bool classof(const Expr *E) { return E->getKind() == ExprKind::Load; }
};

/// This is a conversion from an expression of UnresolvedType to an arbitrary
/// other type, and from an arbitrary type to UnresolvedType.  This node does
/// not appear in valid code, only in code involving diagnostics.
class UnresolvedTypeConversionExpr : public ImplicitConversionExpr {
public:
   UnresolvedTypeConversionExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::UnresolvedTypeConversion, subExpr, type) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedTypeConversion;
   }
};

/// FunctionConversionExpr - Convert a function to another function type,
/// which might involve renaming the parameters or handling substitutions
/// of subtypes (in the return) or supertypes (in the input).
///
/// FIXME: This should be a CapturingExpr.
class FunctionConversionExpr : public ImplicitConversionExpr {
public:
   FunctionConversionExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::FunctionConversion;
   }
};

/// Perform a function conversion from one function that to one that has a
/// covariant result type.
///
/// This conversion is technically unsafe; however, semantic analysis will
/// only introduce such a conversion in cases where other language features
/// (i.e., Self returns) enforce static safety. Additionally, this conversion
/// avoids changing the ABI of the function in question.
class CovariantFunctionConversionExpr : public ImplicitConversionExpr {
public:
   CovariantFunctionConversionExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::CovariantFunctionConversion, subExpr,
                            type) { }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CovariantFunctionConversion;
   }
};

/// Perform a conversion from a superclass to a subclass for a call to
/// a method with a covariant result type.
///
/// This conversion is technically unsafe; however, semantic analysis will
/// only introduce such a conversion in cases where other language features
/// (i.e., Self returns) enforce static safety.
class CovariantReturnConversionExpr : public ImplicitConversionExpr {
public:
   CovariantReturnConversionExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::CovariantReturnConversion, subExpr,
                            type) { }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CovariantReturnConversion;
   }
};

/// Perform a function conversion from a function returning an
/// Optional<T> to a function returning T.
///
/// This is generated during expression type checking in places where
/// we need to force the result type of a function being called. When
/// we go to rewrite the call, we remove this node and force the
/// result of the call to the underlying function. It should never
/// exist outside of this final stage of expression type checking.
class ImplicitlyUnwrappedFunctionConversionExpr
: public ImplicitConversionExpr {
public:
   ImplicitlyUnwrappedFunctionConversionExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::ImplicitlyUnwrappedFunctionConversion,
                            subExpr, type) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ImplicitlyUnwrappedFunctionConversion;
   }
};

/// MetatypeConversionExpr - Convert a metatype to another metatype
/// using essentially a derived-to-base conversion.
class MetatypeConversionExpr : public ImplicitConversionExpr {
public:
   MetatypeConversionExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::MetatypeConversion, subExpr, type) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::MetatypeConversion;
   }
};

/// CollectionUpcastConversionExpr - Convert a collection whose
/// elements have some type T to the same kind of collection whose
/// elements have type U, where U is a subtype of T.
class CollectionUpcastConversionExpr : public ImplicitConversionExpr {
public:
   struct ConversionPair {
      OpaqueValueExpr *OrigValue;
      Expr *Conversion;

      explicit operator bool() const { return OrigValue != nullptr; }
   };
private:
   ConversionPair KeyConversion;
   ConversionPair ValueConversion;
public:
   CollectionUpcastConversionExpr(Expr *subExpr, Type type,
                                  ConversionPair keyConversion,
                                  ConversionPair valueConversion)
   : ImplicitConversionExpr(
   ExprKind::CollectionUpcastConversion, subExpr, type),
     KeyConversion(keyConversion), ValueConversion(valueConversion) {
      assert((!KeyConversion || ValueConversion)
             && "key conversion without value conversion");
   }

   /// Returns the expression that should be used to perform a
   /// conversion of the collection's values; null if the conversion
   /// is formally trivial because the key type does not change.
   const ConversionPair &getKeyConversion() const {
      return KeyConversion;
   }
   void setKeyConversion(const ConversionPair &pair) {
      KeyConversion = pair;
   }

   /// Returns the expression that should be used to perform a
   /// conversion of the collection's values; null if the conversion
   /// is formally trivial because the value type does not change.
   const ConversionPair &getValueConversion() const {
      return ValueConversion;
   }
   void setValueConversion(const ConversionPair &pair) {
      ValueConversion = pair;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CollectionUpcastConversion;
   }
};

/// ErasureExpr - Perform type erasure by converting a value to existential
/// type. For example:
///
/// \code
/// protocol Printable {}
/// struct Book {}
///
/// var printable: Printable = Book() // erases type
/// var printableType: Printable.Type = Book.self // erases metatype
/// \endcode
///
/// The type of the expression should always satisfy isAnyExistentialType().
///
/// The type of the sub-expression should always be either:
///   - a non-existential type of the appropriate kind or
///   - an existential type of the appropriate kind which is a subtype
///     of the result type.
///
/// "Appropriate kind" means e.g. a concrete/existential metatype if the
/// result is an existential metatype.
class ErasureExpr final : public ImplicitConversionExpr,
                          private llvm::TrailingObjects<ErasureExpr, InterfaceConformanceRef> {
   friend TrailingObjects;

   ErasureExpr(Expr *subExpr, Type type,
               ArrayRef<InterfaceConformanceRef> conformances)
   : ImplicitConversionExpr(ExprKind::Erasure, subExpr, type) {
      Bits.ErasureExpr.NumConformances = conformances.size();
      std::uninitialized_copy(conformances.begin(), conformances.end(),
                              getTrailingObjects<InterfaceConformanceRef>());
   }

public:
   static ErasureExpr *create(AstContext &ctx, Expr *subExpr, Type type,
                              ArrayRef<InterfaceConformanceRef> conformances);

   /// Retrieve the mapping specifying how the type of the subexpression
   /// maps to the resulting existential type. If the resulting existential
   /// type involves several different protocols, there will be mappings for each
   /// of those protocols, in the order in which the existential type expands
   /// its properties.
   ///
   /// The entries in this array may be null, indicating that the conformance
   /// to the corresponding protocol is trivial (because the source
   /// type is either an archetype or an existential type that conforms to
   /// that corresponding protocol).
   ArrayRef<InterfaceConformanceRef> getConformances() const {
      return {getTrailingObjects<InterfaceConformanceRef>(),
              Bits.ErasureExpr.NumConformances };
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Erasure;
   }
};

/// AnyHashableErasureExpr - Perform type erasure by converting a value
/// to AnyHashable type.
///
/// The type of the sub-expression should always be a type that implements
/// the Hashable protocol.
class AnyHashableErasureExpr : public ImplicitConversionExpr {
   InterfaceConformanceRef Conformance;

public:
   AnyHashableErasureExpr(Expr *subExpr, Type type,
                          InterfaceConformanceRef conformance)
   : ImplicitConversionExpr(ExprKind::AnyHashableErasure, subExpr, type),
     Conformance(conformance) {}

   /// Retrieve the mapping specifying how the type of the
   /// subexpression conforms to the Hashable protocol.
   InterfaceConformanceRef getConformance() const {
      return Conformance;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::AnyHashableErasure;
   }
};

/// ConditionalBridgeFromObjCExpr - Bridge a value from a non-native
/// representation.
//class ConditionalBridgeFromObjCExpr : public ImplicitConversionExpr {
//   ConcreteDeclRef Conversion;
//
//public:
//   ConditionalBridgeFromObjCExpr(Expr *subExpr, Type type,
//                                 ConcreteDeclRef conversion)
//   : ImplicitConversionExpr(ExprKind::ConditionalBridgeFromObjC, subExpr, type),
//     Conversion(conversion) {
//   }
//
//   /// Retrieve the conversion function.
//   ConcreteDeclRef getConversion() const {
//      return Conversion;
//   }
//
//   static bool classof(const Expr *E) {
//      return E->getKind() == ExprKind::ConditionalBridgeFromObjC;
//   }
//};

// @todo
/// BridgeFromObjCExpr - Bridge a value from a non-native representation.
//class BridgeFromObjCExpr : public ImplicitConversionExpr {
//public:
//   BridgeFromObjCExpr(Expr *subExpr, Type type)
//   : ImplicitConversionExpr(ExprKind::BridgeFromObjC, subExpr, type) {}
//
//   static bool classof(const Expr *E) {
//      return E->getKind() == ExprKind::BridgeFromObjC;
//   }
//};

/// BridgeToObjCExpr - Bridge a value to a non-native representation.
//class BridgeToObjCExpr : public ImplicitConversionExpr {
//public:
//   BridgeToObjCExpr(Expr *subExpr, Type type)
//   : ImplicitConversionExpr(ExprKind::BridgeToObjC, subExpr, type) {}
//
//   static bool classof(const Expr *E) {
//      return E->getKind() == ExprKind::BridgeToObjC;
//   }
//};

/// UnresolvedSpecializeExpr - Represents an explicit specialization using
/// a type parameter list (e.g. "Vector<Int>") that has not been resolved.
class UnresolvedSpecializeExpr final : public Expr,
                                       private llvm::TrailingObjects<UnresolvedSpecializeExpr, TypeLoc> {
   friend TrailingObjects;

   Expr *SubExpr;
   SourceLoc LAngleLoc;
   SourceLoc RAngleLoc;

   UnresolvedSpecializeExpr(Expr *SubExpr,
                            SourceLoc LAngleLoc,
                            ArrayRef<TypeLoc> UnresolvedParams,
                            SourceLoc RAngleLoc)
   : Expr(ExprKind::UnresolvedSpecialize, /*Implicit=*/false),
     SubExpr(SubExpr), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {
      Bits.UnresolvedSpecializeExpr.NumUnresolvedParams = UnresolvedParams.size();
      std::uninitialized_copy(UnresolvedParams.begin(), UnresolvedParams.end(),
                              getTrailingObjects<TypeLoc>());
   }

public:
   static UnresolvedSpecializeExpr *
   create(AstContext &ctx, Expr *SubExpr, SourceLoc LAngleLoc,
          ArrayRef<TypeLoc> UnresolvedParams, SourceLoc RAngleLoc);

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *e) { SubExpr = e; }

   /// Retrieve the list of type parameters. These parameters have not yet
   /// been bound to archetypes of the entity to be specialized.
   ArrayRef<TypeLoc> getUnresolvedParams() const {
      return {getTrailingObjects<TypeLoc>(),
              Bits.UnresolvedSpecializeExpr.NumUnresolvedParams};
   }
   MutableArrayRef<TypeLoc> getUnresolvedParams() {
      return {getTrailingObjects<TypeLoc>(),
              Bits.UnresolvedSpecializeExpr.NumUnresolvedParams};
   }

   SourceLoc getLoc() const { return LAngleLoc; }
   SourceLoc getLAngleLoc() const { return LAngleLoc; }
   SourceLoc getRAngleLoc() const { return RAngleLoc; }

   SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
   SourceLoc getEndLoc() const { return RAngleLoc; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedSpecialize;
   }
};

/// Describes an implicit conversion from a subclass to one of its
/// superclasses.
class DerivedToBaseExpr : public ImplicitConversionExpr {
public:
   DerivedToBaseExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::DerivedToBase, subExpr, type) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DerivedToBase;
   }
};

/// Describes an implicit conversion from a value of archetype type to
/// its concrete superclass.
class ArchetypeToSuperExpr : public ImplicitConversionExpr {
public:
   ArchetypeToSuperExpr(Expr *subExpr, Type type)
   : ImplicitConversionExpr(ExprKind::ArchetypeToSuper, subExpr, type) {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ArchetypeToSuper;
   }
};

/// The builtin unary '&' operator, which converts the
/// given lvalue into an 'inout' argument value.
class InOutExpr : public Expr {
   Expr *SubExpr;
   SourceLoc OperLoc;

public:
   InOutExpr(SourceLoc operLoc, Expr *subExpr, Type baseType,
             bool isImplicit = false);

   SourceLoc getStartLoc() const { return OperLoc; }
   SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }
   SourceLoc getLoc() const { return OperLoc; }

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *e) { SubExpr = e; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::InOut;
   }
};

/// The not-yet-actually-surfaced '...' varargs expansion operator,
/// which splices an array into a sequence of variadic arguments.
class VarargExpansionExpr : public Expr {
   Expr *SubExpr;

public:
   VarargExpansionExpr(Expr *subExpr, bool implicit, Type type = Type())
   : Expr(ExprKind::VarargExpansion, implicit, type), SubExpr(subExpr) {}

   POLAR_FORWARD_SOURCE_LOCS_TO(SubExpr)

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *subExpr) { SubExpr = subExpr; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::VarargExpansion;
   }
};

/// SequenceExpr - A list of binary operations which has not yet been
/// folded into a tree.  The operands all have even indices, while the
/// subexpressions with odd indices are all (potentially overloaded)
/// references to binary operators.
class SequenceExpr final : public Expr,
                           private llvm::TrailingObjects<SequenceExpr, Expr *> {
   friend TrailingObjects;

   SequenceExpr(ArrayRef<Expr*> elements)
   : Expr(ExprKind::Sequence, /*Implicit=*/false) {
      Bits.SequenceExpr.NumElements = elements.size();
      assert(Bits.SequenceExpr.NumElements > 0 && "zero-length sequence!");
      std::uninitialized_copy(elements.begin(), elements.end(),
                              getTrailingObjects<Expr*>());
   }

public:
   static SequenceExpr *create(AstContext &ctx, ArrayRef<Expr*> elements);

   SourceLoc getStartLoc() const {
      return getElement(0)->getStartLoc();
   }
   SourceLoc getEndLoc() const {
      return getElement(getNumElements() - 1)->getEndLoc();
   }

   unsigned getNumElements() const { return Bits.SequenceExpr.NumElements; }

   MutableArrayRef<Expr*> getElements() {
      return {getTrailingObjects<Expr*>(), Bits.SequenceExpr.NumElements};
   }

   ArrayRef<Expr*> getElements() const {
      return {getTrailingObjects<Expr*>(), Bits.SequenceExpr.NumElements};
   }

   Expr *getElement(unsigned i) const {
      return getElements()[i];
   }
   void setElement(unsigned i, Expr *e) {
      getElements()[i] = e;
   }

   // Implement isa/cast/dyncast/etc.
   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Sequence;
   }
};

/// A base class for closure expressions.
class AbstractClosureExpr : public DeclContext, public Expr {
   CaptureInfo Captures;

   /// The set of parameters.
   ParameterList *parameterList;

public:
   AbstractClosureExpr(ExprKind Kind, Type FnType, bool Implicit,
                       unsigned Discriminator, DeclContext *Parent)
   : DeclContext(DeclContextKind::AbstractClosureExpr, Parent),
     Expr(Kind, Implicit, FnType),
     parameterList(nullptr) {
      Bits.AbstractClosureExpr.Discriminator = Discriminator;
   }

   CaptureInfo getCaptureInfo() const { return Captures; }
   void setCaptureInfo(CaptureInfo captures) { Captures = captures; }

   /// Retrieve the parameters of this closure.
   ParameterList *getParameters() { return parameterList; }
   const ParameterList *getParameters() const { return parameterList; }
   void setParameterList(ParameterList *P);

   // Expose this to users.
   using DeclContext::setParent;

   /// Returns a discriminator which determines this expression's index
   /// in the sequence of closure expressions within the current
   /// function.
   ///
   /// There are separate sequences for explicit and implicit closures.
   /// This allows explicit closures to maintain a stable numbering
   /// across simple edits that introduce auto closures above them,
   /// which is the best we can reasonably do.
   ///
   /// (Autoclosures are likely to be eliminated immediately, even in
   /// unoptimized builds, so their names are fairly unimportant.  It's
   /// much more likely that explicit closures will survive
   /// optimization and therefore make it into e.g. stack traces.
   /// Having their symbol names be stable across minor code changes is
   /// therefore pretty useful for debugging.)
   unsigned getDiscriminator() const {
      return Bits.AbstractClosureExpr.Discriminator;
   }
   void setDiscriminator(unsigned discriminator) {
      assert(getDiscriminator() == InvalidDiscriminator);
      assert(discriminator != InvalidDiscriminator);
      Bits.AbstractClosureExpr.Discriminator = discriminator;
   }
   enum : unsigned { InvalidDiscriminator = 0xFFFF };

   /// Retrieve the result type of this closure.
   Type getResultType(llvm::function_ref<Type(const Expr *)> getType =
   [](const Expr *E) -> Type {
      return E->getType();
   }) const;

   /// Return whether this closure is throwing when fully applied.
   bool isBodyThrowing() const;

   /// Whether this closure consists of a single expression.
   bool hasSingleExpressionBody() const;

   /// Retrieve the body for closure that has a single expression for
   /// its body.
   ///
   /// Only valid when \c hasSingleExpressionBody() is true.
   Expr *getSingleExpressionBody() const;

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_AbstractClosureExpr &&
             E->getKind() <= ExprKind::Last_AbstractClosureExpr;
   }

   static bool classof(const DeclContext *DC) {
      return DC->getContextKind() == DeclContextKind::AbstractClosureExpr;
   }

   using DeclContext::operator new;
   using Expr::dump;
};

/// SerializedAbstractClosureExpr - This represents what was originally an
/// AbstractClosureExpr during serialization. It is preserved only to maintain
/// the correct AST structure and remangling after deserialization.
class SerializedAbstractClosureExpr : public SerializedLocalDeclContext {
   const Type Ty;
   llvm::PointerIntPair<Type, 1> TypeAndImplicit;
   const unsigned Discriminator;

public:
   SerializedAbstractClosureExpr(Type Ty, bool Implicit, unsigned Discriminator,
                                 DeclContext *Parent)
   : SerializedLocalDeclContext(LocalDeclContextKind::AbstractClosure,
                                Parent),
     TypeAndImplicit(llvm::PointerIntPair<Type, 1>(Ty, Implicit)),
     Discriminator(Discriminator) {}

   Type getType() const {
      return TypeAndImplicit.getPointer();
   }

   unsigned getDiscriminator() const {
      return Discriminator;
   }

   bool isImplicit() const {
      return TypeAndImplicit.getInt();
   }

   static bool classof(const DeclContext *DC) {
      if (auto LDC = dyn_cast<SerializedLocalDeclContext>(DC))
         return LDC->getLocalDeclContextKind() ==
                LocalDeclContextKind::AbstractClosure;
      return false;
   }
};

/// An explicit unnamed function expression, which can optionally have
/// named arguments.
///
/// \code
///     { $0 + $1 }
///     { a, b -> Int in a + b }
///     { (a : Int, b : Int) -> Int in a + b }
///     { [weak c] (a : Int) -> Int in a + c!.getFoo() }
/// \endcode
class ClosureExpr : public AbstractClosureExpr {

   /// The location of the "throws", if present.
   SourceLoc ThrowsLoc;

   /// The location of the '->' denoting an explicit return type,
   /// if present.
   SourceLoc ArrowLoc;

   /// The location of the "in", if present.
   SourceLoc InLoc;

   /// The explicitly-specified result type.
   TypeLoc ExplicitResultType;

   /// The body of the closure, along with a bit indicating whether it
   /// was originally just a single expression.
   llvm::PointerIntPair<BraceStmt *, 1, bool> Body;

public:
   ClosureExpr(ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc,
               SourceLoc inLoc, TypeLoc explicitResultType,
               unsigned discriminator, DeclContext *parent)
   : AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
                         discriminator, parent),
     ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc),
     ExplicitResultType(explicitResultType),
     Body(nullptr) {
      setParameterList(params);
      Bits.ClosureExpr.HasAnonymousClosureVars = false;
   }

   SourceRange getSourceRange() const;
   SourceLoc getStartLoc() const;
   SourceLoc getEndLoc() const;
   SourceLoc getLoc() const;

   BraceStmt *getBody() const { return Body.getPointer(); }
   void setBody(BraceStmt *S, bool isSingleExpression) {
      Body.setPointer(S);
      Body.setInt(isSingleExpression);
   }

   /// Determine whether the parameters of this closure are actually
   /// anonymous closure variables.
   bool hasAnonymousClosureVars() const {
      return Bits.ClosureExpr.HasAnonymousClosureVars;
   }

   /// Set the parameters of this closure along with a flag indicating
   /// whether these parameters are actually anonymous closure variables.
   void setHasAnonymousClosureVars() {
      Bits.ClosureExpr.HasAnonymousClosureVars = true;
   }

   /// Determine whether this closure expression has an
   /// explicitly-specified result type.
   bool hasExplicitResultType() const { return ArrowLoc.isValid(); }


   /// Retrieve the location of the \c '->' for closures with an
   /// explicit result type.
   SourceLoc getArrowLoc() const {
      assert(hasExplicitResultType() && "No arrow location");
      return ArrowLoc;
   }

   /// Retrieve the location of the \c in for a closure that has it.
   SourceLoc getInLoc() const {
      return InLoc;
   }

   /// Retrieve the location of the 'throws' for a closure that has it.
   SourceLoc getThrowsLoc() const {
      return ThrowsLoc;
   }

   /// Retrieve the explicit result type location information.
   TypeLoc &getExplicitResultTypeLoc() {
      assert(hasExplicitResultType() && "No explicit result type");
      return ExplicitResultType;
   }

   void setExplicitResultType(SourceLoc arrowLoc, TypeLoc resultType) {
      ArrowLoc = arrowLoc;
      ExplicitResultType = resultType;
   }

   /// Determine whether the closure has a single expression for its
   /// body.
   ///
   /// This will be true for closures such as, e.g.,
   /// \code
   ///   { $0 + 1 }
   /// \endcode
   ///
   /// or
   ///
   /// \code
   ///   { x, y in x > y }
   /// \endcode
   ///
   /// ... even if the closure has been coerced to return Void by the type
   /// checker. This function does not return true for empty closures.
   bool hasSingleExpressionBody() const {
      return Body.getInt();
   }

   /// Retrieve the body for closure that has a single expression for
   /// its body.
   ///
   /// Only valid when \c hasSingleExpressionBody() is true.
   Expr *getSingleExpressionBody() const;

   /// Set the body for a closure that has a single expression as its
   /// body.
   ///
   /// This routine cannot change whether a closure has a single expression as
   /// its body; it can only update that expression.
   void setSingleExpressionBody(Expr *NewBody);

   /// Is this a completely empty closure?
   bool hasEmptyBody() const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Closure;
   }
   static bool classof(const AbstractClosureExpr *E) {
      return E->getKind() == ExprKind::Closure;
   }
   static bool classof(const DeclContext *C) {
      return isa<AbstractClosureExpr>(C) && classof(cast<AbstractClosureExpr>(C));
   }
};

/// This is an implicit closure of the contained subexpression that is usually
/// formed when a scalar expression is converted to @autoclosure function type.
/// \code
///   func f(x : @autoclosure () -> Int)
///   f(42)  // AutoclosureExpr convert from Int to ()->Int
/// \endcode
///
///  They are also created when key path expressions are converted to function
///  type, in which case, a pair of nested implicit closures are formed:
/// \code
///   { $kp$ in { $0[keyPath: $kp$] } }( \(E) )
/// \endcode
/// This is to ensure side effects of the key path expression (mainly indices in
/// subscripts) are only evaluated once.
class AutoClosureExpr : public AbstractClosureExpr {
   BraceStmt *Body;

public:
   AutoClosureExpr(Expr *Body, Type ResultTy, unsigned Discriminator,
                   DeclContext *Parent)
   : AbstractClosureExpr(ExprKind::AutoClosure, ResultTy, /*Implicit=*/true,
                         Discriminator, Parent) {
      setBody(Body);
   }

   SourceRange getSourceRange() const;
   SourceLoc getStartLoc() const;
   SourceLoc getEndLoc() const;
   SourceLoc getLoc() const;

   BraceStmt *getBody() const { return Body; }
   void setBody(Expr *E);

   // Expose this to users.
   using DeclContext::setParent;

   /// Returns the body of the autoclosure as an \c Expr.
   ///
   /// The body of an autoclosure always consists of a single expression.
   Expr *getSingleExpressionBody() const;

   // Implement isa/cast/dyncast/etc.
   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::AutoClosure;
   }
   static bool classof(const AbstractClosureExpr *E) {
      return E->getKind() == ExprKind::AutoClosure;
   }
   static bool classof(const DeclContext *C) {
      return isa<AbstractClosureExpr>(C) && classof(cast<AbstractClosureExpr>(C));
   }
};

/// Instances of this structure represent elements of the capture list that can
/// optionally occur in a capture expression.
struct CaptureListEntry {
   VarDecl *Var;
   PatternBindingDecl *Init;

   CaptureListEntry(VarDecl *Var, PatternBindingDecl *Init)
   : Var(Var), Init(Init) {
   }
};

/// CaptureListExpr - This expression represents the capture list on an explicit
/// closure.  Because the capture list is evaluated outside of the closure, this
/// CaptureList wraps the ClosureExpr.  The dynamic semantics are that evaluates
/// the variable bindings from the capture list, then evaluates the
/// subexpression (the closure itself) and returns the result.
class CaptureListExpr final : public Expr,
                              private llvm::TrailingObjects<CaptureListExpr, CaptureListEntry> {
   friend TrailingObjects;

   ClosureExpr *closureBody;

   CaptureListExpr(ArrayRef<CaptureListEntry> captureList,
                   ClosureExpr *closureBody)
   : Expr(ExprKind::CaptureList, /*Implicit=*/false, Type()),
     closureBody(closureBody) {
      Bits.CaptureListExpr.NumCaptures = captureList.size();
      std::uninitialized_copy(captureList.begin(), captureList.end(),
                              getTrailingObjects<CaptureListEntry>());
   }

public:
   static CaptureListExpr *create(AstContext &ctx,
                                  ArrayRef<CaptureListEntry> captureList,
                                  ClosureExpr *closureBody);

   ArrayRef<CaptureListEntry> getCaptureList() {
      return {getTrailingObjects<CaptureListEntry>(),
              Bits.CaptureListExpr.NumCaptures};
   }
   ClosureExpr *getClosureBody() { return closureBody; }
   const ClosureExpr *getClosureBody() const { return closureBody; }

   void setClosureBody(ClosureExpr *body) { closureBody = body; }

   /// This is a bit weird, but the capture list is lexically contained within
   /// the closure, so the ClosureExpr has the full source range.
   POLAR_FORWARD_SOURCE_LOCS_TO(closureBody)

   // Implement isa/cast/dyncast/etc.
   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::CaptureList;
   }
};

/// DynamicTypeExpr - "type(of: base)" - Produces a metatype value.
///
/// The metatype value comes from evaluating an expression then retrieving the
/// metatype of the result.
class DynamicTypeExpr : public Expr {
   SourceLoc KeywordLoc;
   SourceLoc LParenLoc;
   Expr *Base;
   SourceLoc RParenLoc;

public:
   explicit DynamicTypeExpr(SourceLoc KeywordLoc, SourceLoc LParenLoc,
                            Expr *Base, SourceLoc RParenLoc, Type Ty)
   : Expr(ExprKind::DynamicType, /*Implicit=*/false, Ty),
     KeywordLoc(KeywordLoc), LParenLoc(LParenLoc), Base(Base),
     RParenLoc(RParenLoc) { }

   Expr *getBase() const { return Base; }
   void setBase(Expr *base) { Base = base; }

   SourceLoc getLoc() const { return KeywordLoc; }
   SourceRange getSourceRange() const {
      return SourceRange(KeywordLoc, RParenLoc);
   }

   SourceLoc getStartLoc() const {
      return KeywordLoc;
   }
   SourceLoc getEndLoc() const {
      return RParenLoc;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DynamicType;
   }
};

/// An expression referring to an opaque object of a fixed type.
///
/// Opaque value expressions occur when a particular value within the AST
/// needs to be re-used without being re-evaluated or for a value that is
/// a placeholder. OpaqueValueExpr nodes are introduced by some other AST
/// node (say, an \c OpenExistentialExpr) and can only be used within the
/// subexpressions of that AST node.
class OpaqueValueExpr : public Expr {
   SourceRange Range;

public:
   explicit OpaqueValueExpr(SourceRange Range, Type Ty,
                            bool isPlaceholder = false)
   : Expr(ExprKind::OpaqueValue, /*Implicit=*/true, Ty), Range(Range) {
      Bits.OpaqueValueExpr.IsPlaceholder = isPlaceholder;
   }

   /// Whether this opaque value expression represents a placeholder that
   /// is injected before type checking to act as a placeholder for some
   /// value to be specified later.
   bool isPlaceholder() const { return Bits.OpaqueValueExpr.IsPlaceholder; }

   SourceRange getSourceRange() const { return Range; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OpaqueValue;
   }
};

/// An expression referring to a default argument left unspecified at the
/// call site.
///
/// A DefaultArgumentExpr must only appear as a direct child of a
/// ParenExpr or a TupleExpr that is itself a call argument.
class DefaultArgumentExpr final : public Expr {
   friend class CallerSideDefaultArgExprRequest;

   /// The owning declaration.
   ConcreteDeclRef DefaultArgsOwner;

   /// The caller parameter index.
   unsigned ParamIndex;

   /// The source location of the argument list.
   SourceLoc Loc;

   /// Stores either a DeclContext or, upon type-checking, the caller-side
   /// default expression.
   PointerUnion<DeclContext *, Expr *> ContextOrCallerSideExpr;

public:
   explicit DefaultArgumentExpr(ConcreteDeclRef defaultArgsOwner,
                                unsigned paramIndex, SourceLoc loc, Type Ty,
                                DeclContext *dc)
   : Expr(ExprKind::DefaultArgument, /*Implicit=*/true, Ty),
     DefaultArgsOwner(defaultArgsOwner), ParamIndex(paramIndex), Loc(loc),
     ContextOrCallerSideExpr(dc) { }

   SourceRange getSourceRange() const {
      return Loc;
   }

   ConcreteDeclRef getDefaultArgsOwner() const {
      return DefaultArgsOwner;
   }

   unsigned getParamIndex() const {
      return ParamIndex;
   }

   /// Retrieves the parameter declaration for this default argument.
   const ParamDecl *getParamDecl() const;

   /// Checks whether this is a caller-side default argument that is emitted
   /// directly at the call site.
   bool isCallerSide() const;

   /// For a caller-side default argument, retrieves the fully type-checked
   /// expression within the context of the call site.
   Expr *getCallerSideDefaultExpr() const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DefaultArgument;
   }
};

/// ApplyExpr - Superclass of various function calls, which apply an argument to
/// a function to get a result.
class ApplyExpr : public Expr {
   /// The function being called.
   Expr *Fn;

   /// The argument being passed to it, and whether it's a 'super' argument.
   llvm::PointerIntPair<Expr *, 1, bool> ArgAndIsSuper;

   /// Returns true if \c e could be used as the call's argument. For most \c ApplyExpr
   /// subclasses, this means it is a \c ParenExpr or \c TupleExpr.
   bool validateArg(Expr *e) const;

protected:
   ApplyExpr(ExprKind Kind, Expr *Fn, Expr *Arg, bool Implicit, Type Ty = Type())
   : Expr(Kind, Implicit, Ty), Fn(Fn), ArgAndIsSuper(Arg, false) {
      assert(classof((Expr*)this) && "ApplyExpr::classof out of date");
      assert(validateArg(Arg) && "Arg is not a permitted expr kind");
      Bits.ApplyExpr.ThrowsIsSet = false;
   }

public:
   Expr *getFn() const { return Fn; }
   void setFn(Expr *e) { Fn = e; }
   Expr *getSemanticFn() const { return Fn->getSemanticsProvidingExpr(); }

   Expr *getArg() const { return ArgAndIsSuper.getPointer(); }
   void setArg(Expr *e) {
      assert(validateArg(e) && "Arg is not a permitted expr kind");
      ArgAndIsSuper = {e, ArgAndIsSuper.getInt()};
   }

   bool isSuper() const { return ArgAndIsSuper.getInt(); }
   void setIsSuper(bool super) {
      ArgAndIsSuper = {ArgAndIsSuper.getPointer(), super};
   }

   /// Has the type-checker set the 'throws' bit yet?
   ///
   /// In general, this should only be used for debugging purposes.
   bool isThrowsSet() const { return Bits.ApplyExpr.ThrowsIsSet; }

   /// Does this application throw?  This is only meaningful after
   /// complete type-checking.
   ///
   /// If true, the function expression must have a throwing function
   /// type.  The converse is not true because of 'rethrows' functions.
   bool throws() const {
      assert(Bits.ApplyExpr.ThrowsIsSet);
      return Bits.ApplyExpr.Throws;
   }
   void setThrows(bool throws) {
      assert(!Bits.ApplyExpr.ThrowsIsSet);
      Bits.ApplyExpr.ThrowsIsSet = true;
      Bits.ApplyExpr.Throws = throws;
   }

   ValueDecl *getCalledValue() const;

   /// Retrieve the argument labels provided at the call site.
   ///
   /// \param scratch Scratch space that will be used when the argument labels
   /// aren't already stored in the AST context.
   ArrayRef<Identifier>
   getArgumentLabels(SmallVectorImpl<Identifier> &scratch) const;

   /// Whether this application was written using a trailing closure.
   bool hasTrailingClosure() const;

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_ApplyExpr &&
             E->getKind() <= ExprKind::Last_ApplyExpr;
   }
};

/// CallExpr - Application of an argument to a function, which occurs
/// syntactically through juxtaposition with a TupleExpr whose
/// leading '(' is unspaced.
class CallExpr final : public ApplyExpr,
                       public TrailingCallArguments<CallExpr> {
   friend TrailingCallArguments;

   CallExpr(Expr *fn, Expr *arg, bool Implicit,
            ArrayRef<Identifier> argLabels,
            ArrayRef<SourceLoc> argLabelLocs,
            bool hasTrailingClosure,
            Type ty);

public:
   /// Create a new call expression.
   ///
   /// Note: prefer to use the entry points that separate out the arguments.
   static CallExpr *
   create(AstContext &ctx, Expr *fn, Expr *arg, ArrayRef<Identifier> argLabels,
          ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure,
          bool implicit, Type type = Type(),
          llvm::function_ref<Type(const Expr *)> getType =
          [](const Expr *E) -> Type { return E->getType(); });

   /// Create a new implicit call expression without any source-location
   /// information.
   ///
   /// \param fn The function being called
   /// \param args The call arguments, not including a trailing closure (if any).
   /// \param argLabels The argument labels, whose size must equal args.size(),
   /// or which must be empty.
   static CallExpr *
   createImplicit(AstContext &ctx, Expr *fn, ArrayRef<Expr *> args,
                  ArrayRef<Identifier> argLabels,
                  llvm::function_ref<Type(const Expr *)> getType =
                  [](const Expr *E) -> Type { return E->getType(); }) {
      return create(ctx, fn, SourceLoc(), args, argLabels, { }, SourceLoc(),
      /*trailingClosure=*/nullptr, /*implicit=*/true, getType);
   }

   /// Create a new call expression.
   ///
   /// \param fn The function being called
   /// \param args The call arguments, not including a trailing closure (if any).
   /// \param argLabels The argument labels, whose size must equal args.size(),
   /// or which must be empty.
   /// \param argLabelLocs The locations of the argument labels, whose size must
   /// equal args.size() or which must be empty.
   /// \param trailingClosure The trailing closure, if any.
   static CallExpr *
   create(AstContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
          ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
          SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
          llvm::function_ref<Type(const Expr *)> getType =
          [](const Expr *E) -> Type { return E->getType(); });

   SourceLoc getStartLoc() const {
      SourceLoc fnLoc = getFn()->getStartLoc();
      return (fnLoc.isValid() ? fnLoc : getArg()->getStartLoc());
   }
   SourceLoc getEndLoc() const {
      SourceLoc argLoc = getArg()->getEndLoc();
      return (argLoc.isValid() ? argLoc : getFn()->getEndLoc());
   }

   SourceLoc getLoc() const {
      SourceLoc FnLoc = getFn()->getLoc();
      return FnLoc.isValid() ? FnLoc : getArg()->getLoc();
   }

   unsigned getNumArguments() const { return Bits.CallExpr.NumArgLabels; }
   bool hasArgumentLabelLocs() const { return Bits.CallExpr.HasArgLabelLocs; }

   /// Whether this call with written with a trailing closure.
   bool hasTrailingClosure() const { return Bits.CallExpr.HasTrailingClosure; }

   using TrailingCallArguments::getArgumentLabels;

   /// Retrieve the expression that directly represents the callee.
   ///
   /// The "direct" callee is the expression representing the callee
   /// after looking through top-level constructs that don't affect the
   /// identity of the callee, e.g., extra parentheses, optional
   /// unwrapping (?)/forcing (!), etc.
   Expr *getDirectCallee() const;

   static bool classof(const Expr *E) { return E->getKind() == ExprKind::Call; }
};

/// PrefixUnaryExpr - Prefix unary expressions like '!y'.
class PrefixUnaryExpr : public ApplyExpr {
public:
   PrefixUnaryExpr(Expr *Fn, Expr *Arg, Type Ty = Type())
   : ApplyExpr(ExprKind::PrefixUnary, Fn, Arg, /*Implicit=*/false, Ty) {}

   SourceLoc getLoc() const { return getFn()->getStartLoc(); }

   SourceLoc getStartLoc() const {
      return getFn()->getStartLoc();
   }
   SourceLoc getEndLoc() const {
      return getArg()->getEndLoc();
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::PrefixUnary;
   }
};

/// PostfixUnaryExpr - Postfix unary expressions like 'y!'.
class PostfixUnaryExpr : public ApplyExpr {
public:
   PostfixUnaryExpr(Expr *Fn, Expr *Arg, Type Ty = Type())
   : ApplyExpr(ExprKind::PostfixUnary, Fn, Arg, /*Implicit=*/false, Ty) {}

   SourceLoc getLoc() const { return getFn()->getStartLoc(); }

   SourceLoc getStartLoc() const {
      return getArg()->getStartLoc();
   }
   SourceLoc getEndLoc() const {
      return getFn()->getEndLoc();
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::PostfixUnary;
   }
};

/// BinaryExpr - Infix binary expressions like 'x+y'.  The argument is always
/// an implicit tuple expression of the type expected by the function.
class BinaryExpr : public ApplyExpr {
public:
   BinaryExpr(Expr *Fn, TupleExpr *Arg, bool Implicit, Type Ty = Type())
   : ApplyExpr(ExprKind::Binary, Fn, Arg, Implicit, Ty) {}

   SourceLoc getLoc() const { return getFn()->getLoc(); }

   SourceRange getSourceRange() const { return getArg()->getSourceRange(); }
   SourceLoc getStartLoc() const { return getArg()->getStartLoc(); }
   SourceLoc getEndLoc() const { return getArg()->getEndLoc(); }

   TupleExpr *getArg() const { return cast<TupleExpr>(ApplyExpr::getArg()); }

   static bool classof(const Expr *E) { return E->getKind() == ExprKind::Binary;}
};

/// SelfApplyExpr - Abstract application that provides the 'self' pointer for
/// a method curried as (this : Self) -> (params) -> result.
///
/// The application of a curried method to 'self' semantically differs from
/// normal function application because the 'self' parameter can be implicitly
/// materialized from an rvalue.
class SelfApplyExpr : public ApplyExpr {
protected:
   SelfApplyExpr(ExprKind K, Expr *FnExpr, Expr *BaseExpr, Type Ty)
   : ApplyExpr(K, FnExpr, BaseExpr, FnExpr->isImplicit(), Ty) { }

public:
   Expr *getBase() const { return getArg(); }
   void setBase(Expr *E) { setArg(E); }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_SelfApplyExpr &&
             E->getKind() <= ExprKind::Last_SelfApplyExpr;
   }
};

/// DotSyntaxCallExpr - Refer to a method of a type, e.g. P.x.  'x'
/// is modeled as a DeclRefExpr or OverloadSetRefExpr on the method.
class DotSyntaxCallExpr : public SelfApplyExpr {
   SourceLoc DotLoc;

public:
   DotSyntaxCallExpr(Expr *FnExpr, SourceLoc DotLoc, Expr *BaseExpr,
                     Type Ty = Type())
   : SelfApplyExpr(ExprKind::DotSyntaxCall, FnExpr, BaseExpr, Ty),
     DotLoc(DotLoc) {
      setImplicit(DotLoc.isInvalid());
   }

   SourceLoc getDotLoc() const { return DotLoc; }

   SourceLoc getLoc() const {
      return isImplicit() ? getBase()->getStartLoc() : getFn()->getLoc();
   }
   SourceLoc getStartLoc() const {
      return getBase()->getStartLoc();
   }
   SourceLoc getEndLoc() const {
      return isImplicit() ? getBase()->getEndLoc() : getFn()->getEndLoc();
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DotSyntaxCall;
   }
};

/// ConstructorRefCallExpr - Refer to a constructor for a type P.  The
/// actual reference to function which returns the constructor is modeled
/// as a DeclRefExpr.
class ConstructorRefCallExpr : public SelfApplyExpr {
public:
   ConstructorRefCallExpr(Expr *FnExpr, Expr *BaseExpr, Type Ty = Type())
   : SelfApplyExpr(ExprKind::ConstructorRefCall, FnExpr, BaseExpr, Ty) {}

   SourceLoc getLoc() const { return getFn()->getLoc(); }
   SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
   SourceLoc getEndLoc() const { return getFn()->getEndLoc(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ConstructorRefCall;
   }
};

/// DotSyntaxBaseIgnoredExpr - When a.b resolves to something that does not need
/// the actual value of the base (e.g. when applied to a metatype, module, or
/// the base of a 'static' function) this expression node is created.  The
/// semantics are that its base is evaluated and discarded, then 'b' is
/// evaluated and returned as the result of the expression.
class DotSyntaxBaseIgnoredExpr : public Expr {
   Expr *LHS;
   SourceLoc DotLoc;
   Expr *RHS;
public:
   DotSyntaxBaseIgnoredExpr(Expr *LHS, SourceLoc DotLoc, Expr *RHS, Type rhsTy)
   : Expr(ExprKind::DotSyntaxBaseIgnored, /*Implicit=*/false, rhsTy),
     LHS(LHS), DotLoc(DotLoc), RHS(RHS) {
   }

   Expr *getLHS() const { return LHS; }
   void setLHS(Expr *E) { LHS = E; }
   SourceLoc getDotLoc() const { return DotLoc; }
   Expr *getRHS() const { return RHS; }
   void setRHS(Expr *E) { RHS = E; }

   SourceLoc getStartLoc() const {
      return DotLoc.isValid() ? LHS->getStartLoc() : RHS->getStartLoc();
   }
   SourceLoc getEndLoc() const { return RHS->getEndLoc(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::DotSyntaxBaseIgnored;
   }
};

/// Represents an explicit cast, 'a as T' or 'a is T', where "T" is a
/// type, and "a" is the expression that will be converted to the type.
class ExplicitCastExpr : public Expr {
   Expr *SubExpr;
   SourceLoc AsLoc;
   TypeLoc CastTy;

protected:
   ExplicitCastExpr(ExprKind kind, Expr *sub, SourceLoc AsLoc, TypeLoc castTy,
                    Type resultTy)
   : Expr(kind, /*Implicit=*/false), SubExpr(sub), AsLoc(AsLoc), CastTy(castTy)
   {}

public:
   Expr *getSubExpr() const { return SubExpr; }

   /// Get the type syntactically spelled in the cast. For some forms of checked
   /// cast this is different from the result type of the expression.
   TypeLoc &getCastTypeLoc() { return CastTy; }

   /// Get the type syntactically spelled in the cast. For some forms of checked
   /// cast this is different from the result type of the expression.
   TypeLoc getCastTypeLoc() const { return CastTy; }

   void setSubExpr(Expr *E) { SubExpr = E; }

   SourceLoc getLoc() const {
      if (AsLoc.isValid())
         return AsLoc;

      return SubExpr->getLoc();
   }

   SourceLoc getAsLoc() const {
      return AsLoc;
   }

   SourceRange getSourceRange() const {
      SourceRange castTyRange = CastTy.getSourceRange();
      if (castTyRange.isInvalid())
         return SubExpr->getSourceRange();

      auto startLoc = SubExpr ? SubExpr->getStartLoc() : AsLoc;
      auto endLoc = castTyRange.end;

      return {startLoc, endLoc};
   }

   /// True if the node has been processed by SequenceExpr folding.
   bool isFolded() const { return SubExpr; }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_ExplicitCastExpr &&
             E->getKind() <= ExprKind::Last_ExplicitCastExpr;
   }
};

/// Return a string representation of a CheckedCastKind.
StringRef getCheckedCastKindName(CheckedCastKind kind);

/// Abstract base class for checked casts 'as' and 'is'. These represent
/// casts that can dynamically fail.
class CheckedCastExpr : public ExplicitCastExpr {
public:
   CheckedCastExpr(ExprKind kind,
                   Expr *sub, SourceLoc asLoc, TypeLoc castTy, Type resultTy)
   : ExplicitCastExpr(kind, sub, asLoc, castTy, resultTy)
   {
      Bits.CheckedCastExpr.CastKind = unsigned(CheckedCastKind::Unresolved);
   }

   /// Return the semantic kind of cast performed.
   CheckedCastKind getCastKind() const {
      return CheckedCastKind(Bits.CheckedCastExpr.CastKind);
   }
   void setCastKind(CheckedCastKind kind) {
      Bits.CheckedCastExpr.CastKind = unsigned(kind);
   }

   /// True if the cast has been type-checked and its kind has been set.
   bool isResolved() const {
      return getCastKind() >= CheckedCastKind::First_Resolved;
   }

   static bool classof(const Expr *E) {
      return E->getKind() >= ExprKind::First_CheckedCastExpr
             && E->getKind() <= ExprKind::Last_CheckedCastExpr;
   }
};

/// Represents an explicit forced checked cast, which converts
/// from a value of some type to some specified subtype and fails dynamically
/// if the value does not have that type.
/// Spelled 'a as! T' and produces a value of type 'T'.
class ForcedCheckedCastExpr : public CheckedCastExpr {
   SourceLoc ExclaimLoc;

public:
   ForcedCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc exclaimLoc,
                         TypeLoc type)
   : CheckedCastExpr(ExprKind::ForcedCheckedCast,
                     sub, asLoc, type, type.getType()),
     ExclaimLoc(exclaimLoc)
   {
   }

   ForcedCheckedCastExpr(SourceLoc asLoc, SourceLoc exclaimLoc, TypeLoc type)
   : ForcedCheckedCastExpr(nullptr, asLoc, exclaimLoc, type)
   {
   }

   /// Retrieve the location of the '!' that follows 'as'.
   SourceLoc getExclaimLoc() const { return ExclaimLoc; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ForcedCheckedCast;
   }
};

/// Represents an explicit conditional checked cast, which converts
/// from a type to some subtype and produces an Optional value, which will be
/// .Some(x) if the cast succeeds, or .None if the cast fails.
/// Spelled 'a as? T' and produces a value of type 'T?'.
class ConditionalCheckedCastExpr : public CheckedCastExpr {
   SourceLoc QuestionLoc;

public:
   ConditionalCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc questionLoc,
                              TypeLoc type)
   : CheckedCastExpr(ExprKind::ConditionalCheckedCast,
                     sub, asLoc, type, type.getType()),
     QuestionLoc(questionLoc)
   { }

   ConditionalCheckedCastExpr(SourceLoc asLoc, SourceLoc questionLoc,
                              TypeLoc type)
   : ConditionalCheckedCastExpr(nullptr, asLoc, questionLoc, type)
   {}

   /// Retrieve the location of the '?' that follows 'as'.
   SourceLoc getQuestionLoc() const { return QuestionLoc; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::ConditionalCheckedCast;
   }
};

/// Represents a runtime type check query, 'a is T', where 'T' is a type
/// and 'a' is a value of some related type. Evaluates to a Bool true if 'a' is
/// of the type and 'a as T' would succeed, false otherwise.
///
/// FIXME: We should support type queries with a runtime metatype value too.
class IsExpr : public CheckedCastExpr {
public:
   IsExpr(Expr *sub, SourceLoc isLoc, TypeLoc type)
   : CheckedCastExpr(ExprKind::Is,
                     sub, isLoc, type, Type())
   {}

   IsExpr(SourceLoc isLoc, TypeLoc type)
   : IsExpr(nullptr, isLoc, type)
   {}

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Is;
   }
};

/// Represents an explicit coercion from a value to a specific type.
///
/// Spelled 'a as T' and produces a value of type 'T'.
class CoerceExpr : public ExplicitCastExpr {
   /// Since there is already `asLoc` location,
   /// we use it to store `start` of the initializer
   /// call source range to save some storage.
   SourceLoc InitRangeEnd;

public:
   CoerceExpr(Expr *sub, SourceLoc asLoc, TypeLoc type)
   : ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type, type.getType())
   { }

   CoerceExpr(SourceLoc asLoc, TypeLoc type)
   : CoerceExpr(nullptr, asLoc, type)
   { }

private:
   CoerceExpr(SourceRange initRange, Expr *literal, TypeLoc type)
   : ExplicitCastExpr(ExprKind::Coerce, literal, initRange.start,
                      type, type.getType()), InitRangeEnd(initRange.end)
   { setImplicit(); }

public:
   /// Create an implicit coercion expression for literal initialization
   /// preserving original source information, this way original call
   /// could be recreated if needed.
   static CoerceExpr *forLiteralInit(AstContext &ctx, Expr *literal,
                                     SourceRange range, TypeLoc literalType) {
      return new (ctx) CoerceExpr(range, literal, literalType);
   }

   bool isLiteralInit() const { return InitRangeEnd.isValid(); }

   SourceRange getSourceRange() const {
      return isLiteralInit()
             ? SourceRange(getAsLoc(), InitRangeEnd)
             : ExplicitCastExpr::getSourceRange();
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Coerce;
   }
};

/// Represents two expressions joined by the arrow operator '->', which
/// may be preceded by the 'throws' keyword. Currently this only exists to be
/// transformed into a FunctionTypeRepr by simplifyTypeExpr() in Sema.
class ArrowExpr : public Expr {
   SourceLoc ThrowsLoc;
   SourceLoc ArrowLoc;
   Expr *Args;
   Expr *Result;
public:
   ArrowExpr(Expr *Args, SourceLoc ThrowsLoc, SourceLoc ArrowLoc, Expr *Result)
   : Expr(ExprKind::Arrow, /*implicit=*/false, Type()),
     ThrowsLoc(ThrowsLoc), ArrowLoc(ArrowLoc), Args(Args), Result(Result)
   { }

   ArrowExpr(SourceLoc ThrowsLoc, SourceLoc ArrowLoc)
   : Expr(ExprKind::Arrow, /*implicit=*/false, Type()),
     ThrowsLoc(ThrowsLoc), ArrowLoc(ArrowLoc), Args(nullptr), Result(nullptr)
   { }

   Expr *getArgsExpr() const { return Args; }
   void setArgsExpr(Expr *E) { Args = E; }
   Expr *getResultExpr() const { return Result; }
   void setResultExpr(Expr *E) { Result = E; }
   SourceLoc getThrowsLoc() const { return ThrowsLoc; }
   SourceLoc getArrowLoc() const { return ArrowLoc; }
   bool isFolded() const { return Args != nullptr && Result != nullptr; }

   SourceLoc getSourceLoc() const { return ArrowLoc; }
   SourceLoc getStartLoc() const {
      return isFolded() ? Args->getStartLoc() :
             ThrowsLoc.isValid() ? ThrowsLoc : ArrowLoc;
   }
   SourceLoc getEndLoc() const {
      return isFolded() ? Result->getEndLoc() : ArrowLoc;
   }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Arrow;
   }
};

/// Represents the rebinding of 'self' in a constructor that calls out
/// to another constructor. The result of the subexpression is assigned to
/// 'self', and the expression returns void.
///
/// When a super.init or delegating initializer is invoked, 'self' is
/// reassigned to the result of the initializer (after being downcast in the
/// case of super.init).
///
/// This is needed for reference types with ObjC interop, where
/// reassigning 'self' is a supported feature, and for value type delegating
/// constructors, where the delegatee constructor is responsible for
/// initializing 'self' in-place before the delegator's logic executes.
class RebindSelfInConstructorExpr : public Expr {
   Expr *SubExpr;
   VarDecl *Self;
public:
   RebindSelfInConstructorExpr(Expr *SubExpr, VarDecl *Self);

   POLAR_FORWARD_SOURCE_LOCS_TO(SubExpr)

   VarDecl *getSelf() const { return Self; }
   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *Sub) { SubExpr = Sub; }

   OtherConstructorDeclRefExpr *getCalledConstructor(bool &isChainToSuper) const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::RebindSelfInConstructor;
   }
};

/// The conditional expression 'x ? y : z'.
class IfExpr : public Expr {
   Expr *CondExpr, *ThenExpr, *ElseExpr;
   SourceLoc QuestionLoc, ColonLoc;
public:
   IfExpr(Expr *CondExpr,
          SourceLoc QuestionLoc, Expr *ThenExpr,
          SourceLoc ColonLoc, Expr *ElseExpr,
          Type Ty = Type())
   : Expr(ExprKind::If, /*Implicit=*/false, Ty),
     CondExpr(CondExpr), ThenExpr(ThenExpr), ElseExpr(ElseExpr),
     QuestionLoc(QuestionLoc), ColonLoc(ColonLoc)
   {}

   IfExpr(SourceLoc QuestionLoc, Expr *ThenExpr, SourceLoc ColonLoc)
   : IfExpr(nullptr, QuestionLoc, ThenExpr, ColonLoc, nullptr)
   {}

   SourceLoc getLoc() const { return QuestionLoc; }
   SourceLoc getStartLoc() const {
      return (isFolded() ? CondExpr->getStartLoc() : QuestionLoc);
   }
   SourceLoc getEndLoc() const {
      return (isFolded() ? ElseExpr->getEndLoc() : ColonLoc);
   }
   SourceLoc getQuestionLoc() const { return QuestionLoc; }
   SourceLoc getColonLoc() const { return ColonLoc; }

   Expr *getCondExpr() const { return CondExpr; }
   void setCondExpr(Expr *E) { CondExpr = E; }

   Expr *getThenExpr() const { return ThenExpr; }
   void setThenExpr(Expr *E) { ThenExpr = E; }

   Expr *getElseExpr() const { return ElseExpr; }
   void setElseExpr(Expr *E) { ElseExpr = E; }

   /// True if the node has been processed by binary expression folding.
   bool isFolded() const { return CondExpr && ElseExpr; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::If;
   }
};

/// EnumIsCaseExpr - A boolean expression that is true if an enum value is of
/// a particular case.
class EnumIsCaseExpr : public Expr {
   Expr *SubExpr;
   EnumElementDecl *Element;

public:
   EnumIsCaseExpr(Expr *SubExpr, EnumElementDecl *Element)
   : Expr(ExprKind::EnumIsCase, /*implicit*/ true),
     SubExpr(SubExpr), Element(Element)
   {}

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *e) { SubExpr = e; }

   EnumElementDecl *getEnumElement() const { return Element; }
   void setEnumElement(EnumElementDecl *elt) { Element = elt; }

   SourceLoc getLoc() const { return SubExpr->getLoc(); }
   SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
   SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::EnumIsCase;
   }
};

/// AssignExpr - A value assignment, like "x = y".
class AssignExpr : public Expr {
   Expr *Dest;
   Expr *Src;
   SourceLoc EqualLoc;

public:
   AssignExpr(Expr *Dest, SourceLoc EqualLoc, Expr *Src, bool Implicit)
   : Expr(ExprKind::Assign, Implicit),
     Dest(Dest), Src(Src), EqualLoc(EqualLoc) {}

   AssignExpr(SourceLoc EqualLoc)
   : AssignExpr(nullptr, EqualLoc, nullptr, /*Implicit=*/false)
   {}

   Expr *getDest() const { return Dest; }
   void setDest(Expr *e) { Dest = e; }
   Expr *getSrc() const { return Src; }
   void setSrc(Expr *e) { Src = e; }

   SourceLoc getEqualLoc() const { return EqualLoc; }

   SourceLoc getLoc() const {
      SourceLoc loc = EqualLoc;
      if (loc.isValid()) {
         return loc;
      }
      return getStartLoc();
   }
   SourceLoc getStartLoc() const {
      if (!isFolded()) return EqualLoc;
      return ( Dest->getStartLoc().isValid()
               ? Dest->getStartLoc()
               : Src->getStartLoc());
   }
   SourceLoc getEndLoc() const {
      if (!isFolded()) return EqualLoc;
      auto SrcEnd = Src->getEndLoc();
      return (SrcEnd.isValid() ? SrcEnd : Dest->getEndLoc());
   }

   /// True if the node has been processed by binary expression folding.
   bool isFolded() const { return Dest && Src; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::Assign;
   }
};

/// A pattern production that has been parsed but hasn't been resolved
/// into a complete pattern. Name binding converts these into standalone pattern
/// nodes or raises an error if a pattern production appears in an invalid
/// position.
class UnresolvedPatternExpr : public Expr {
   Pattern *subPattern;

public:
   explicit UnresolvedPatternExpr(Pattern *subPattern)
   : Expr(ExprKind::UnresolvedPattern, /*Implicit=*/false),
     subPattern(subPattern) { }

   const Pattern *getSubPattern() const { return subPattern; }
   Pattern *getSubPattern() { return subPattern; }
   void setSubPattern(Pattern *p) { subPattern = p; }

   SourceRange getSourceRange() const;
   SourceLoc getStartLoc() const;
   SourceLoc getEndLoc() const;
   SourceLoc getLoc() const;

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::UnresolvedPattern;
   }
};


/// An editor placeholder (<#such as this#>) that occurred in an expression
/// context. If the placeholder is a typed one (see \c EditorPlaceholderData)
/// its type string will be typechecked and will be associated with this expr.
class EditorPlaceholderExpr : public Expr {
   Identifier Placeholder;
   SourceLoc Loc;
   TypeLoc PlaceholderTy;
   TypeRepr *ExpansionTyR;
   Expr *SemanticExpr;

public:
   EditorPlaceholderExpr(Identifier Placeholder, SourceLoc Loc,
                         TypeLoc PlaceholderTy,
                         TypeRepr *ExpansionTyR)
   : Expr(ExprKind::EditorPlaceholder, /*Implicit=*/false),
     Placeholder(Placeholder), Loc(Loc),
     PlaceholderTy(PlaceholderTy),
     ExpansionTyR(ExpansionTyR),
     SemanticExpr(nullptr) {
   }

   Identifier getPlaceholder() const { return Placeholder; }
   SourceRange getSourceRange() const { return Loc; }
   TypeLoc &getTypeLoc() { return PlaceholderTy; }
   TypeLoc getTypeLoc() const { return PlaceholderTy; }
   SourceLoc getTrailingAngleBracketLoc() const {
      return Loc.getAdvancedLoc(Placeholder.getLength() - 1);
   }

   /// The TypeRepr to be considered for placeholder expansion.
   TypeRepr *getTypeForExpansion() const { return ExpansionTyR; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::EditorPlaceholder;
   }

   Expr *getSemanticExpr() const { return SemanticExpr; }
   void setSemanticExpr(Expr *SE) { SemanticExpr = SE; }
};

/// A LazyInitializerExpr is used to embed an existing typechecked
/// expression --- like the initializer of a lazy variable --- into an
/// untypechecked AST.
class LazyInitializerExpr : public Expr {
   Expr *SubExpr;
public:
   LazyInitializerExpr(Expr *subExpr)
   : Expr(ExprKind::LazyInitializer, /*implicit*/ true),
     SubExpr(subExpr) {}

   SourceRange getSourceRange() const { return SubExpr->getSourceRange(); }
   SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
   SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }
   SourceLoc getLoc() const { return SubExpr->getLoc(); }

   Expr *getSubExpr() const { return SubExpr; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::LazyInitializer;
   }
};

/// Produces the Objective-C selector of the referenced method.
///
/// \code
/// #selector(UIView.insertSubview(_:aboveSubview:))
/// \endcode
//class ObjCSelectorExpr : public Expr {
//   SourceLoc KeywordLoc;
//   SourceLoc LParenLoc;
//   SourceLoc ModifierLoc;
//   Expr *SubExpr;
//   SourceLoc RParenLoc;
//   AbstractFunctionDecl *ResolvedMethod = nullptr;
//
//public:
//   /// The kind of #selector expression this is.
//   enum ObjCSelectorKind {
//      Method, Getter, Setter
//   };
//
//   ObjCSelectorExpr(ObjCSelectorKind kind, SourceLoc keywordLoc,
//                    SourceLoc lParenLoc, SourceLoc modifierLoc, Expr *subExpr,
//                    SourceLoc rParenLoc)
//   : Expr(ExprKind::ObjCSelector, /*Implicit=*/false),
//     KeywordLoc(keywordLoc), LParenLoc(lParenLoc),
//     ModifierLoc(modifierLoc), SubExpr(subExpr), RParenLoc(rParenLoc) {
//      Bits.ObjCSelectorExpr.SelectorKind = static_cast<unsigned>(kind);
//   }
//
//   Expr *getSubExpr() const { return SubExpr; }
//   void setSubExpr(Expr *expr) { SubExpr = expr; }
//
//   /// Whether this selector references a property getter or setter.
//   bool isPropertySelector() const {
//      switch (getSelectorKind()) {
//         case ObjCSelectorKind::Method:
//            return false;
//
//         case ObjCSelectorKind::Getter:
//         case ObjCSelectorKind::Setter:
//            return true;
//      }
//
//      llvm_unreachable("Unhandled ObjcSelectorKind in switch.");
//   }
//
//   /// Whether this selector references a method.
//   bool isMethodSelector() const {
//      switch (getSelectorKind()) {
//         case ObjCSelectorKind::Method:
//            return true;
//
//         case ObjCSelectorKind::Getter:
//         case ObjCSelectorKind::Setter:
//            return false;
//      }
//   }
//
//   /// Retrieve the Objective-C method to which this expression refers.
//   AbstractFunctionDecl *getMethod() const { return ResolvedMethod; }
//
//   /// Set the Objective-C method to which this expression refers.
//   void setMethod(AbstractFunctionDecl *method) { ResolvedMethod = method; }
//
//   SourceLoc getLoc() const { return KeywordLoc; }
//   SourceRange getSourceRange() const {
//      return SourceRange(KeywordLoc, RParenLoc);
//   }
//
//   /// The location at which the getter: or setter: starts. Requires the selector
//   /// to be a getter or setter.
//   SourceLoc getModifierLoc() const {
//      assert(isPropertySelector() && "Modifiers only set on property selectors");
//      return ModifierLoc;
//   }
//
//   /// Retrieve the kind of the selector (method, getter, setter)
//   ObjCSelectorKind getSelectorKind() const {
//      return static_cast<ObjCSelectorKind>(Bits.ObjCSelectorExpr.SelectorKind);
//   }
//
//   /// Override the selector kind.
//   ///
//   /// Used by the type checker to recover from ill-formed #selector
//   /// expressions.
//   void overrideObjCSelectorKind(ObjCSelectorKind newKind,
//                                 SourceLoc modifierLoc) {
//      Bits.ObjCSelectorExpr.SelectorKind = static_cast<unsigned>(newKind);
//      ModifierLoc = modifierLoc;
//   }
//
//   static bool classof(const Expr *E) {
//      return E->getKind() == ExprKind::ObjCSelector;
//   }
//};

/// Produces a keypath string for the given referenced property.
///
/// \code
/// #keyPath(Person.friends.firstName)
/// \endcode
class KeyPathExpr : public Expr {
   SourceLoc StartLoc;
   SourceLoc LParenLoc;
   SourceLoc EndLoc;
   Expr *ObjCStringLiteralExpr = nullptr;

   // The parsed root of a Swift keypath (the section before an unusual dot, like
   // Foo.Bar in \Foo.Bar.?.baz).
   Expr *ParsedRoot = nullptr;
   // The parsed path of a Swift keypath (the section after an unusual dot, like
   // ?.baz in \Foo.Bar.?.baz).
   Expr *ParsedPath = nullptr;

   // The processed/resolved type, like Foo.Bar in \Foo.Bar.?.baz.
   TypeRepr *RootType = nullptr;

public:
   /// A single stored component, which will be one of:
   /// - an unresolved DeclName, which has to be type-checked
   /// - a resolved ValueDecl, referring to
   /// - a subscript index expression, which may or may not be resolved
   /// - an optional chaining, forcing, or wrapping component
   class Component {
   public:
      enum class Kind: unsigned {
         Invalid,
         UnresolvedProperty,
         UnresolvedSubscript,
         Property,
         Subscript,
         OptionalForce,
         OptionalChain,
         OptionalWrap,
         Identity,
         TupleElement,
      };

   private:
      union DeclNameOrRef {
         DeclName UnresolvedName;
         ConcreteDeclRef ResolvedDecl;

         DeclNameOrRef() : UnresolvedName{} {}
         DeclNameOrRef(DeclName un) : UnresolvedName(un) {}
         DeclNameOrRef(ConcreteDeclRef rd) : ResolvedDecl(rd) {}
      } Decl;


      Expr *SubscriptIndexExpr;
      const Identifier *SubscriptLabelsData;
      const InterfaceConformanceRef *SubscriptHashableConformancesData;

      union {
         unsigned SubscriptSize;
         unsigned TupleIndex;
      };

      Kind KindValue;
      Type ComponentType;
      SourceLoc Loc;

      explicit Component(AstContext *ctxForCopyingLabels,
                         DeclNameOrRef decl,
                         Expr *indexExpr,
                         ArrayRef<Identifier> subscriptLabels,
                         ArrayRef<InterfaceConformanceRef> indexHashables,
                         Kind kind,
                         Type type,
                         SourceLoc loc);

      // Private constructor for tuple element kind
      Component(unsigned tupleIndex, Type elementType, SourceLoc loc)
      : Component(nullptr, {}, nullptr, {}, {}, Kind::TupleElement,
                  elementType, loc) {
         TupleIndex = tupleIndex;
      }

   public:
      Component()
      : Component(nullptr, {}, nullptr, {}, {}, Kind::Invalid,
                  Type(), SourceLoc())
      {}

      /// Create an unresolved component for a property.
      static Component forUnresolvedProperty(DeclName UnresolvedName,
                                             SourceLoc Loc) {
         return Component(nullptr,
                          UnresolvedName, nullptr, {}, {},
                          Kind::UnresolvedProperty,
                          Type(),
                          Loc);
      }

      /// Create an unresolved component for a subscript.
      static Component forUnresolvedSubscript(AstContext &ctx,
                                              SourceLoc lSquareLoc,
                                              ArrayRef<Expr *> indexArgs,
                                              ArrayRef<Identifier> indexArgLabels,
                                              ArrayRef<SourceLoc> indexArgLabelLocs,
                                              SourceLoc rSquareLoc,
                                              Expr *trailingClosure);

      /// Create an unresolved component for a subscript.
      ///
      /// You shouldn't add new uses of this overload; use the one that takes a
      /// list of index arguments.
      static Component forUnresolvedSubscriptWithPrebuiltIndexExpr(
      AstContext &context,
      Expr *index,
      ArrayRef<Identifier> subscriptLabels,
      SourceLoc loc) {

         return Component(&context,
                          {}, index, subscriptLabels, {},
                          Kind::UnresolvedSubscript,
                          Type(), loc);
      }

      /// Create an unresolved optional force `!` component.
      static Component forUnresolvedOptionalForce(SourceLoc BangLoc) {
         return Component(nullptr, {}, nullptr, {}, {},
                          Kind::OptionalForce,
                          Type(),
                          BangLoc);
      }

      /// Create an unresolved optional chain `?` component.
      static Component forUnresolvedOptionalChain(SourceLoc QuestionLoc) {
         return Component(nullptr, {}, nullptr, {}, {},
                          Kind::OptionalChain,
                          Type(),
                          QuestionLoc);
      }

      /// Create a component for a property.
      static Component forProperty(ConcreteDeclRef property,
                                   Type propertyType,
                                   SourceLoc loc) {
         return Component(nullptr, property, nullptr, {}, {},
                          Kind::Property,
                          propertyType,
                          loc);
      }

      /// Create a component for a subscript.
      static Component forSubscript(AstContext &ctx,
                                    ConcreteDeclRef subscript,
                                    SourceLoc lSquareLoc,
                                    ArrayRef<Expr *> indexArgs,
                                    ArrayRef<Identifier> indexArgLabels,
                                    ArrayRef<SourceLoc> indexArgLabelLocs,
                                    SourceLoc rSquareLoc,
                                    Expr *trailingClosure,
                                    Type elementType,
                                    ArrayRef<InterfaceConformanceRef> indexHashables);

      /// Create a component for a subscript.
      ///
      /// You shouldn't add new uses of this overload; use the one that takes a
      /// list of index arguments.
      static Component forSubscriptWithPrebuiltIndexExpr(
      ConcreteDeclRef subscript, Expr *index, ArrayRef<Identifier> labels,
      Type elementType, SourceLoc loc,
      ArrayRef<InterfaceConformanceRef> indexHashables);

      /// Create an optional-forcing `!` component.
      static Component forOptionalForce(Type forcedType, SourceLoc bangLoc) {
         return Component(nullptr, {}, nullptr, {}, {},
                          Kind::OptionalForce, forcedType,
                          bangLoc);
      }

      /// Create an optional-chaining `?` component.
      static Component forOptionalChain(Type unwrappedType,
                                        SourceLoc questionLoc) {
         return Component(nullptr, {}, nullptr, {}, {},
                          Kind::OptionalChain, unwrappedType,
                          questionLoc);
      }

      /// Create an optional-wrapping component. This doesn't have a surface
      /// syntax but may appear when the non-optional result of an optional chain
      /// is implicitly wrapped.
      static Component forOptionalWrap(Type wrappedType) {
         return Component(nullptr, {}, nullptr, {}, {},
                          Kind::OptionalWrap, wrappedType,
                          SourceLoc());
      }

      static Component forIdentity(SourceLoc selfLoc) {
         return Component(nullptr, {}, nullptr, {}, {},
                          Kind::Identity, Type(),
                          selfLoc);
      }

      static Component forTupleElement(unsigned fieldNumber,
                                       Type elementType,
                                       SourceLoc loc) {
         return Component(fieldNumber, elementType, loc);
      }


      SourceLoc getLoc() const {
         return Loc;
      }

      Kind getKind() const {
         return KindValue;
      }

      bool isValid() const {
         return getKind() != Kind::Invalid;
      }

      bool isResolved() const {
         if (!getComponentType())
            return false;

         switch (getKind()) {
            case Kind::Subscript:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::Property:
            case Kind::Identity:
            case Kind::TupleElement:
               return true;

            case Kind::UnresolvedSubscript:
            case Kind::UnresolvedProperty:
            case Kind::Invalid:
               return false;
         }
         llvm_unreachable("unhandled kind");
      }

      Expr *getIndexExpr() const {
         switch (getKind()) {
            case Kind::Subscript:
            case Kind::UnresolvedSubscript:
               return SubscriptIndexExpr;

            case Kind::Invalid:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::UnresolvedProperty:
            case Kind::Property:
            case Kind::Identity:
            case Kind::TupleElement:
               return nullptr;
         }
         llvm_unreachable("unhandled kind");
      }

      ArrayRef<Identifier> getSubscriptLabels() const {
         switch (getKind()) {
            case Kind::Subscript:
            case Kind::UnresolvedSubscript:
               return {SubscriptLabelsData, (size_t)SubscriptSize};

            case Kind::Invalid:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::UnresolvedProperty:
            case Kind::Property:
            case Kind::Identity:
            case Kind::TupleElement:
               llvm_unreachable("no subscript labels for this kind");
         }
         llvm_unreachable("unhandled kind");
      }

      ArrayRef<InterfaceConformanceRef>
      getSubscriptIndexHashableConformances() const {
         switch (getKind()) {
            case Kind::Subscript:
               if (!SubscriptHashableConformancesData)
                  return {};
               return {SubscriptHashableConformancesData, (size_t)SubscriptSize};

            case Kind::UnresolvedSubscript:
            case Kind::Invalid:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::UnresolvedProperty:
            case Kind::Property:
            case Kind::Identity:
            case Kind::TupleElement:
               return {};
         }
         llvm_unreachable("unhandled kind");
      }

      void setSubscriptIndexHashableConformances(
      ArrayRef<InterfaceConformanceRef> hashables);

      DeclName getUnresolvedDeclName() const {
         switch (getKind()) {
            case Kind::UnresolvedProperty:
               return Decl.UnresolvedName;

            case Kind::Invalid:
            case Kind::Subscript:
            case Kind::UnresolvedSubscript:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::Property:
            case Kind::Identity:
            case Kind::TupleElement:
               llvm_unreachable("no unresolved name for this kind");
         }
         llvm_unreachable("unhandled kind");
      }

      ConcreteDeclRef getDeclRef() const {
         switch (getKind()) {
            case Kind::Property:
            case Kind::Subscript:
               return Decl.ResolvedDecl;

            case Kind::Invalid:
            case Kind::UnresolvedProperty:
            case Kind::UnresolvedSubscript:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::Identity:
            case Kind::TupleElement:
               llvm_unreachable("no decl ref for this kind");
         }
         llvm_unreachable("unhandled kind");
      }

      unsigned getTupleIndex() const {
         switch (getKind()) {
            case Kind::TupleElement:
               return TupleIndex;

            case Kind::Invalid:
            case Kind::UnresolvedProperty:
            case Kind::UnresolvedSubscript:
            case Kind::OptionalChain:
            case Kind::OptionalWrap:
            case Kind::OptionalForce:
            case Kind::Identity:
            case Kind::Property:
            case Kind::Subscript:
               llvm_unreachable("no field number for this kind");
         }
         llvm_unreachable("unhandled kind");
      }

      Type getComponentType() const {
         return ComponentType;
      }

      void setComponentType(Type t) {
         ComponentType = t;
      }
   };

private:
   llvm::MutableArrayRef<Component> Components;

public:
   /// Create a new #keyPath expression.
   KeyPathExpr(AstContext &C,
               SourceLoc keywordLoc, SourceLoc lParenLoc,
               ArrayRef<Component> components,
               SourceLoc rParenLoc,
               bool isImplicit = false);

   KeyPathExpr(SourceLoc backslashLoc, Expr *parsedRoot, Expr *parsedPath,
               bool isImplicit = false)
   : Expr(ExprKind::KeyPath, isImplicit), StartLoc(backslashLoc),
     EndLoc(parsedPath ? parsedPath->getEndLoc() : parsedRoot->getEndLoc()),
     ParsedRoot(parsedRoot), ParsedPath(parsedPath) {
      assert((parsedRoot || parsedPath) &&
             "keypath must have either root or path");
      Bits.KeyPathExpr.IsObjC = false;
   }

   SourceLoc getLoc() const { return StartLoc; }
   SourceRange getSourceRange() const { return SourceRange(StartLoc, EndLoc); }

   /// Get the components array.
   ArrayRef<Component> getComponents() const {
      return Components;
   }
   MutableArrayRef<Component> getMutableComponents() {
      return Components;
   }

   /// Resolve the components of an un-type-checked expr. This copies over the
   /// components from the argument array.
   void resolveComponents(AstContext &C,
                          ArrayRef<Component> resolvedComponents);

   /// Retrieve the string literal expression, which will be \c NULL prior to
   /// type checking and a string literal after type checking for an
   /// @objc key path.
   Expr *getObjCStringLiteralExpr() const {
      return ObjCStringLiteralExpr;
   }

   /// Set the semantic expression.
   void setObjCStringLiteralExpr(Expr *expr) {
      ObjCStringLiteralExpr = expr;
   }

   Expr *getParsedRoot() const {
      return ParsedRoot;
   }
   void setParsedRoot(Expr *root) {
      ParsedRoot = root;
   }

   Expr *getParsedPath() const {
      return ParsedPath;
   }
   void setParsedPath(Expr *path) {
      ParsedPath = path;
   }

   TypeRepr *getRootType() const {
      return RootType;
   }
   void setRootType(TypeRepr *rootType) {
      RootType = rootType;
   }

//   /// True if this is an ObjC key path expression.
//   bool isObjC() const { return Bits.KeyPathExpr.IsObjC; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::KeyPath;
   }
};

/// Represents the unusual behavior of a . in a \ keypath expression, such as
/// \.[0] and \Foo.?.
class KeyPathDotExpr : public Expr {
   SourceLoc DotLoc;

public:
   KeyPathDotExpr(SourceLoc dotLoc)
   : Expr(ExprKind::KeyPathDot, /*isImplicit=*/true), DotLoc(dotLoc) {}

   SourceLoc getLoc() const { return DotLoc; }
   SourceRange getSourceRange() const { return SourceRange(DotLoc, DotLoc); }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::KeyPathDot;
   }
};

/// Expression node that effects a "one-way" constraint in
/// the constraint system, allowing type information to flow from the
/// subexpression outward but not the other way.
///
/// One-way expressions are generally implicit and synthetic, introduced by
/// the type checker. However, there is a built-in expression of the
/// form \c Builtin.one_way(x) that forms a one-way constraint coming out
/// of expression `x` that can be used for testing purposes.
class OneWayExpr : public Expr {
   Expr *SubExpr;

public:
   /// Construct an implicit one-way expression from the given subexpression.
   OneWayExpr(Expr *subExpr)
   : Expr(ExprKind::OneWay, /*isImplicit=*/true), SubExpr(subExpr) { }

   SourceLoc getLoc() const { return SubExpr->getLoc(); }
   SourceRange getSourceRange() const { return SubExpr->getSourceRange(); }

   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *subExpr) { SubExpr = subExpr; }

   static bool classof(const Expr *E) {
      return E->getKind() == ExprKind::OneWay;
   }
};

inline bool Expr::isInfixOperator() const {
   return isa<BinaryExpr>(this) || isa<IfExpr>(this) ||
          isa<AssignExpr>(this) || isa<ExplicitCastExpr>(this);
}

inline bool ApplyExpr::validateArg(Expr *e) const {
   if (isa<SelfApplyExpr>(this))
      return true;
   else if (isa<BinaryExpr>(this))
      return isa<TupleExpr>(e);
   else
      return isa<ParenExpr>(e) || isa<TupleExpr>(e);
}

inline Expr *const *CollectionExpr::getTrailingObjectsPointer() const {
   if (auto ty = dyn_cast<ArrayExpr>(this))
      return ty->getTrailingObjects<Expr*>();
   if (auto ty = dyn_cast<DictionaryExpr>(this))
      return ty->getTrailingObjects<Expr*>();
   llvm_unreachable("Unhandled CollectionExpr!");
}

inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
   if (auto ty = dyn_cast<ArrayExpr>(this))
      return ty->getTrailingObjects<SourceLoc>();
   if (auto ty = dyn_cast<DictionaryExpr>(this))
      return ty->getTrailingObjects<SourceLoc>();
   llvm_unreachable("Unhandled CollectionExpr!");
}

#undef POLAR_FORWARD_SOURCE_LOCS_TO

/// Pack the argument information into a single argument, to match the
/// representation expected by the AST.
///
/// \param argLabels The argument labels, which might be updated by this
/// function.
///
/// \param argLabelLocs The argument label locations, which might be updated by
/// this function.
Expr *packSingleArgument(AstContext &ctx, SourceLoc lParenLoc,
                         ArrayRef<Expr *> args,
                         ArrayRef<Identifier> &argLabels,
                         ArrayRef<SourceLoc> &argLabelLocs,
                         SourceLoc rParenLoc,
                         Expr *trailingClosure, bool implicit,
                         SmallVectorImpl<Identifier> &argLabelsScratch,
                         SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
                         llvm::function_ref<Type(const Expr *)> getType =
                         [](const Expr *E) -> Type {
                            return E->getType();
                         });

void simple_display(llvm::raw_ostream &out, const ClosureExpr *CE);
void simple_display(llvm::raw_ostream &out, const DefaultArgumentExpr *expr);

SourceLoc extractNearestSourceLoc(const DefaultArgumentExpr *expr);

} // end namespace polar

#endif
